Skip to content

Commit 55de6f4

Browse files
authored
SampleGen: Add function-level documentation (#216)
Generates function-level comments. - a comment describing what the sample does. Generated from description field in sample config. - comments describing what each parameter is. Generated from request.comment field in sample config.
1 parent c7c946d commit 55de6f4

File tree

6 files changed

+116
-17
lines changed

6 files changed

+116
-17
lines changed

cmd/gen-go-sample/inittree.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -522,19 +522,19 @@ func (t *initTree) print(w *bufio.Writer, g *generator, ind int) error {
522522
}
523523

524524
for i, k := range t.keys {
525-
printCommentLines(w, t.vals[i].comment, ind + 1)
525+
printCommentLines(w, t.vals[i].comment, ind+1)
526526
if t.vals[i].typ.namePat != nil {
527527
for _, v := range t.vals[i].vals {
528-
printCommentLines(w, v.comment, ind + 1)
528+
printCommentLines(w, v.comment, ind+1)
529529
}
530530
}
531-
indent(w, ind + 1)
531+
indent(w, ind+1)
532532

533533
var closeBrace bool
534534
if oneof, ok := oneofs[k]; ok {
535535
fmt.Fprintf(w, "%s: &%s.%s_%s{\n", snakeToPascal(oneof), impSpec.Name, typName, snakeToPascal(k))
536536
closeBrace = true
537-
indent(w, ind + 2)
537+
indent(w, ind+2)
538538
}
539539

540540
if writeKey {
@@ -548,7 +548,7 @@ func (t *initTree) print(w *bufio.Writer, g *generator, ind int) error {
548548

549549
if closeBrace {
550550
w.WriteString(",\n")
551-
indent(w, ind + 1)
551+
indent(w, ind+1)
552552
w.WriteByte('}')
553553
}
554554
w.WriteString(",\n")

cmd/gen-go-sample/main.go

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,7 @@ func (g *generator) disambiguateSampleIDs() error {
313313
return nil
314314
}
315315

316+
// TODO(hzyi): this method is getting long. Split it up.
316317
func (g *generator) genSample(sampConf schema_v1p2.Sample, methConf GAPICMethod) error {
317318
ifaceName := sampConf.Service
318319

@@ -353,14 +354,41 @@ func (g *generator) genSample(sampConf schema_v1p2.Sample, methConf GAPICMethod)
353354

354355
p := g.pt.Printf
355356

356-
// Region tag, function signature and new client
357+
// Region tag
357358
argStr, err := argListStr(initInfo, g)
358359
if err != nil {
359360
return err
360361
}
361362
p("")
362363
p("// [START %s]", sampConf.RegionTag)
363364
p("")
365+
366+
// comments above the sample function
367+
requiresNewLine := false
368+
369+
writeCommentLines := func(comment string) {
370+
comment = strings.TrimSpace(comment)
371+
writeComment(comment, nil, g)
372+
}
373+
374+
if sampConf.Description != "" {
375+
writeCommentLines(fmt.Sprintf("sample%s: %s", meth.GetName(), sampConf.Description))
376+
requiresNewLine = true
377+
}
378+
379+
for i, argName := range initInfo.argNames {
380+
comment := initInfo.argTrees[i].comment
381+
if comment == "" {
382+
continue
383+
}
384+
if requiresNewLine {
385+
writeCommentLines("")
386+
}
387+
requiresNewLine = true
388+
writeCommentLines(fmt.Sprintf("%s: %s", argName, comment))
389+
}
390+
391+
// function signature and client initialization
364392
p("func sample%s(%s) error {", meth.GetName(), argStr)
365393
p(" ctx := context.Background()")
366394
p(" c, err := %s.New%sClient(ctx)", g.clientPkg.Name, pbinfo.ReduceServName(serv.GetName(), g.clientPkg.Name))
@@ -689,3 +717,42 @@ func prependLines(b *bytes.Buffer, prefix string, skipEmptyLine bool) {
689717
b.WriteString(l)
690718
}
691719
}
720+
721+
// wrapComment wraps comment at 100 characters, iff comment does not contain any newline characters
722+
// and comment has more than 110 characters.
723+
//
724+
// comment cannot have leading or trailing white spaces.
725+
func wrapComment(comment string) string {
726+
if strings.ContainsRune(comment, '\n') || len(comment) < 110 {
727+
return comment
728+
}
729+
730+
var output strings.Builder
731+
s := 0
732+
prev := -1
733+
734+
for true {
735+
fmt.Println("what")
736+
p := strings.IndexByte(comment[prev+1:], ' ')
737+
// we reached the end of comment
738+
if p < 0 {
739+
output.WriteString(comment[s:])
740+
return output.String()
741+
}
742+
743+
p = p + prev + 1
744+
if p-s > 100 {
745+
// a single word has more than 100 characters
746+
if prev == s-1 {
747+
prev = p
748+
}
749+
// break the line at prev
750+
output.WriteString(comment[s:prev])
751+
output.WriteByte('\n')
752+
s = prev + 1
753+
}
754+
prev = p
755+
}
756+
757+
return ""
758+
}

cmd/gen-go-sample/main_test.go

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,15 @@ func TestUnary(t *testing.T) {
3333
g := initTestGenerator()
3434

3535
sp := schema_v1p2.Sample{
36-
ID: "my_sample_config",
37-
Rpc: "UnaryMethod",
38-
Service: "foo.FooService",
39-
RegionTag: "awesome_region",
36+
ID: "my_sample_config",
37+
Rpc: "UnaryMethod",
38+
Service: "foo.FooService",
39+
RegionTag: "awesome_region",
40+
Description: "Construct a complex request object,\nsend it to the server,\nand inspect the response.\n",
4041
Request: []schema_v1p2.RequestConfig{
41-
{Field: "a.x", Value: "42", InputParameter: "the_x"},
42+
{Field: "a.x", Value: "42", InputParameter: "the_x", Comment: "a single-line comment for an input parameter"},
4243
{Field: "a.y", Value: "3.14159", Comment: "approximation of Pi"},
43-
{Field: "b", Value: "foobar", InputParameter: "the_b"},
44+
{Field: "b", Value: "foobar", InputParameter: "the_b", Comment: "a multi-line comment for\nan input parameter\n"},
4445
{Field: "e", Value: "BANANA"},
4546
{Field: "f", Value: "in a oneof"},
4647
{Field: "bytes", Value: "mybytes"},
@@ -427,6 +428,29 @@ func TestEnum(t *testing.T) {
427428
compare(t, g, filepath.Join("testdata", "sample_enum.want"))
428429
}
429430

431+
func TestWrapCommentNotWrapping(t *testing.T) {
432+
comment := "some short comments"
433+
if c := wrapComment(comment); c != comment {
434+
t.Fatal(errors.E(nil, "want %q, got %q", comment, c))
435+
}
436+
437+
comment = "some\nmulti-line\ncomments"
438+
if c := wrapComment(comment); c != comment {
439+
t.Fatal(errors.E(nil, "want %q, got %q", comment, c))
440+
}
441+
}
442+
443+
func TestWrapCommentWrapping(t *testing.T) {
444+
raw := "The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog again. The quick brown fox jumps over the lazy dog again and again."
445+
wrapped :=
446+
`The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog again. The
447+
quick brown fox jumps over the lazy dog again and again.`
448+
449+
if c := wrapComment(raw); c != wrapped {
450+
t.Fatal(errors.E(nil, "want %q, got %q", wrapped, c))
451+
}
452+
}
453+
430454
func initTestGenerator() *generator {
431455
eType := &descriptor.EnumDescriptorProto{
432456
Name: proto.String("FruitEnum"),

cmd/gen-go-sample/testdata/sample_unary.want

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,14 @@ foopb "path.to/pb/foo"
2828

2929
// [START awesome_region]
3030

31+
// sampleUnaryMethod: Construct a complex request object,
32+
// send it to the server,
33+
// and inspect the response.
34+
//
35+
// theX: a single-line comment for an input parameter
36+
//
37+
// theB: a multi-line comment for
38+
// an input parameter
3139
func sampleUnaryMethod(theX int64, theB string, theFoo string, bobFile string) error {
3240
ctx := context.Background()
3341
c, err := foo.NewClient(ctx)

internal/gengapic/client_init.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ func (g *generator) clientOptions(serv *descriptor.ServiceDescriptorProto, servN
9797
if name.GetMethod() != "" {
9898
base = base + "." + name.GetMethod()
9999
policies[base] = mc.GetRetryPolicy()
100-
100+
101101
if maxReq := mc.GetMaxRequestMessageBytes(); maxReq != nil {
102102
reqLimits[base] = int(maxReq.GetValue())
103103
}
@@ -148,7 +148,7 @@ func (g *generator) clientOptions(serv *descriptor.ServiceDescriptorProto, servN
148148
mFQN := sFQN + "." + m.GetName()
149149
p("%s: []gax.CallOption{", m.GetName())
150150

151-
if maxReq, ok := reqLimits[mFQN]; ok {
151+
if maxReq, ok := reqLimits[mFQN]; ok {
152152
p("gax.WithGRPCOptions(grpc.MaxCallSendMsgSize(%d)),", maxReq)
153153
}
154154

internal/gengapic/client_init_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,12 @@ import (
2121
"github.com/golang/protobuf/proto"
2222
"github.com/golang/protobuf/protoc-gen-go/descriptor"
2323
"github.com/golang/protobuf/ptypes/duration"
24+
wrappers "github.com/golang/protobuf/ptypes/wrappers"
2425
conf "github.com/googleapis/gapic-generator-go/internal/grpc_service_config"
2526
"github.com/googleapis/gapic-generator-go/internal/pbinfo"
2627
"github.com/googleapis/gapic-generator-go/internal/txtdiff"
2728
"google.golang.org/genproto/googleapis/api/annotations"
2829
code "google.golang.org/genproto/googleapis/rpc/code"
29-
wrappers "github.com/golang/protobuf/ptypes/wrappers"
3030
)
3131

3232
func TestClientOpt(t *testing.T) {
@@ -41,7 +41,7 @@ func TestClientOpt(t *testing.T) {
4141
Method: "Zip",
4242
},
4343
},
44-
MaxRequestMessageBytes: &wrappers.UInt32Value{Value: 123456},
44+
MaxRequestMessageBytes: &wrappers.UInt32Value{Value: 123456},
4545
MaxResponseMessageBytes: &wrappers.UInt32Value{Value: 123456},
4646
RetryOrHedgingPolicy: &conf.MethodConfig_RetryPolicy_{
4747
RetryPolicy: &conf.MethodConfig_RetryPolicy{
@@ -60,7 +60,7 @@ func TestClientOpt(t *testing.T) {
6060
Service: "bar.FooService",
6161
},
6262
},
63-
MaxRequestMessageBytes: &wrappers.UInt32Value{Value: 654321},
63+
MaxRequestMessageBytes: &wrappers.UInt32Value{Value: 654321},
6464
MaxResponseMessageBytes: &wrappers.UInt32Value{Value: 654321},
6565
RetryOrHedgingPolicy: &conf.MethodConfig_RetryPolicy_{
6666
RetryPolicy: &conf.MethodConfig_RetryPolicy{

0 commit comments

Comments
 (0)