Skip to content

Commit 9e7e4b4

Browse files
authored
feat: adds patch support, updates workflow input suffix (#32)
* feat: updates workflow input suffix to avoid conflicts Many protobuf implementations use Input and Output for rpc method message suffixes. The Input suffix conflicts with the workflow input struct generated by this plugin. This modifies the code generation logic to use the WorkflowInput suffix for the generated workflow input structs, however, given that this has the potential to break existing usage, this change can be disabled via a new plugin option: ```shell --go_temporal_opt=disable-workflow-input-rename=true ``` ```yaml plugins: - plugin: go_temporal out: gen opt: disable-workflow-input-rename=true strategy: all ``` * feat: adds experimental support for alta/protopatch * feat: adds experimental support for alta/protopatch * fixup! Merge branch 'cludden/patch' of github.com:cludden/protoc-gen-go-temporal into cludden/patch
1 parent 72bc0e1 commit 9e7e4b4

File tree

22 files changed

+1132
-330
lines changed

22 files changed

+1132
-330
lines changed

buf.gen.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@ managed:
44
go_package_prefix:
55
default: github.com/cludden/protoc-gen-go-temporal/gen
66
plugins:
7-
- plugin: go
7+
- plugin: go-patch
88
out: gen
9-
opt: paths=source_relative
9+
opt: plugin=go,paths=source_relative
1010
- plugin: go_temporal
1111
out: gen
12-
opt: paths=source_relative,cli-enabled=true,cli-categories=true,workflow-update-enabled=true
12+
opt: paths=source_relative,cli-enabled=true,cli-categories=true,enable-patch-support=true,workflow-update-enabled=true
1313
strategy: all
1414
- plugin: doc
1515
out: docs/api

docs/api/patch/api.md

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
# Protocol Documentation
2+
<a name="top"></a>
3+
4+
## Table of Contents
5+
6+
- [patch/go.proto](#patch_go-proto)
7+
- [LintOptions](#go-LintOptions)
8+
- [Options](#go-Options)
9+
10+
- [File-level Extensions](#patch_go-proto-extensions)
11+
- [File-level Extensions](#patch_go-proto-extensions)
12+
- [File-level Extensions](#patch_go-proto-extensions)
13+
- [File-level Extensions](#patch_go-proto-extensions)
14+
- [File-level Extensions](#patch_go-proto-extensions)
15+
- [File-level Extensions](#patch_go-proto-extensions)
16+
17+
- [Scalar Value Types](#scalar-value-types)
18+
19+
20+
21+
<a name="patch_go-proto"></a>
22+
<p align="right"><a href="#top">Top</a></p>
23+
24+
## patch/go.proto
25+
26+
27+
28+
<a name="go-LintOptions"></a>
29+
30+
### LintOptions
31+
LintOptions represent options for linting a generated Go file.
32+
33+
34+
| Field | Type | Label | Description |
35+
| ----- | ---- | ----- | ----------- |
36+
| all | [bool](#bool) | optional | Set all to true if all generated Go symbols should be linted. This option affects generated structs, struct fields, enum types, and value constants. |
37+
| messages | [bool](#bool) | optional | Set messages to true if message names should be linted. This does not affect message fields. |
38+
| fields | [bool](#bool) | optional | Set messages to true if message field names should be linted. This does not affect message fields. |
39+
| enums | [bool](#bool) | optional | Set enums to true if generated enum names should be linted. This does not affect enum values. |
40+
| values | [bool](#bool) | optional | Set values to true if generated enum value constants should be linted. |
41+
| extensions | [bool](#bool) | optional | Set extensions to true if generated extension names should be linted. |
42+
| initialisms | [string](#string) | repeated | The initialisms option lets you specify strings that should not be generated as mixed-case, Examples: ID, URL, HTTP, etc. |
43+
44+
45+
46+
47+
48+
49+
<a name="go-Options"></a>
50+
51+
### Options
52+
Options represent Go-specific options for Protobuf messages, fields, oneofs, enums, or enum values.
53+
54+
55+
| Field | Type | Label | Description |
56+
| ----- | ---- | ----- | ----------- |
57+
| name | [string](#string) | optional | The name option renames the generated Go identifier and related identifiers. For a message, this renames the generated Go struct and nested messages or enums, if any. For a message field, this renames the generated Go struct field and getter method. For a oneof field, this renames the generated Go struct field, getter method, interface type, and wrapper types. For an enum, this renames the generated Go type. For an enum value, this renames the generated Go const. |
58+
| embed | [bool](#bool) | optional | The embed option indicates the field should be embedded in the generated Go struct. Only message types can be embedded. Oneof fields cannot be embedded. See https://golang.org/ref/spec#Struct_types. |
59+
| type | [string](#string) | optional | The type option changes the generated field type. All generated code assumes that this type is castable to the protocol buffer field type. |
60+
| getter | [string](#string) | optional | The getter option renames the generated getter method (default: Get&lt;Field&gt;) so a custom getter can be implemented in its place.
61+
62+
TODO: implement this |
63+
| tags | [string](#string) | optional | The tags option specifies additional struct tags which are appended a generated Go struct field. This option may be specified on a message field or a oneof field. The value should omit the enclosing backticks. |
64+
| stringer | [string](#string) | optional | The stringer option renames a generated String() method (if any) so a custom String() method can be implemented in its place.
65+
66+
TODO: implement for messages |
67+
| stringer_name | [string](#string) | optional | The stringer_name option is a deprecated alias for stringer. It will be removed in a future version of this package. |
68+
69+
70+
71+
72+
73+
74+
75+
76+
77+
78+
<a name="patch_go-proto-extensions"></a>
79+
80+
### File-level Extensions
81+
| Extension | Type | Base | Number | Description |
82+
| --------- | ---- | ---- | ------ | ----------- |
83+
| enum | Options | .google.protobuf.EnumOptions | 7001 | |
84+
| value | Options | .google.protobuf.EnumValueOptions | 7001 | |
85+
| field | Options | .google.protobuf.FieldOptions | 7001 | |
86+
| lint | LintOptions | .google.protobuf.FileOptions | 7001 | |
87+
| message | Options | .google.protobuf.MessageOptions | 7001 | |
88+
| oneof | Options | .google.protobuf.OneofOptions | 7001 | |
89+
90+
91+
92+
93+
94+
95+
96+
## Scalar Value Types
97+
98+
| .proto Type | Notes | C++ | Java | Python | Go | C# | PHP | Ruby |
99+
| ----------- | ----- | --- | ---- | ------ | -- | -- | --- | ---- |
100+
| <a name="double" /> double | | double | double | float | float64 | double | float | Float |
101+
| <a name="float" /> float | | float | float | float | float32 | float | float | Float |
102+
| <a name="int32" /> int32 | Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint32 instead. | int32 | int | int | int32 | int | integer | Bignum or Fixnum (as required) |
103+
| <a name="int64" /> int64 | Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint64 instead. | int64 | long | int/long | int64 | long | integer/string | Bignum |
104+
| <a name="uint32" /> uint32 | Uses variable-length encoding. | uint32 | int | int/long | uint32 | uint | integer | Bignum or Fixnum (as required) |
105+
| <a name="uint64" /> uint64 | Uses variable-length encoding. | uint64 | long | int/long | uint64 | ulong | integer/string | Bignum or Fixnum (as required) |
106+
| <a name="sint32" /> sint32 | Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int32s. | int32 | int | int | int32 | int | integer | Bignum or Fixnum (as required) |
107+
| <a name="sint64" /> sint64 | Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int64s. | int64 | long | int/long | int64 | long | integer/string | Bignum |
108+
| <a name="fixed32" /> fixed32 | Always four bytes. More efficient than uint32 if values are often greater than 2^28. | uint32 | int | int | uint32 | uint | integer | Bignum or Fixnum (as required) |
109+
| <a name="fixed64" /> fixed64 | Always eight bytes. More efficient than uint64 if values are often greater than 2^56. | uint64 | long | int/long | uint64 | ulong | integer/string | Bignum |
110+
| <a name="sfixed32" /> sfixed32 | Always four bytes. | int32 | int | int | int32 | int | integer | Bignum or Fixnum (as required) |
111+
| <a name="sfixed64" /> sfixed64 | Always eight bytes. | int64 | long | int/long | int64 | long | integer/string | Bignum |
112+
| <a name="bool" /> bool | | bool | boolean | boolean | bool | bool | boolean | TrueClass/FalseClass |
113+
| <a name="string" /> string | A string must always contain UTF-8 encoded or 7-bit ASCII text. | string | String | str/unicode | string | string | string | String (UTF-8) |
114+
| <a name="bytes" /> bytes | May contain any arbitrary sequence of bytes. | string | ByteString | str | []byte | ByteString | string | String (ASCII-8BIT) |
115+

example/main.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,15 @@ type Workflows struct{}
2525
type CreateFooWorkflow struct {
2626
// it embeds the generated workflow Input type that contains the workflow
2727
// input and signal helpers
28-
*examplev1.CreateFooInput
28+
*examplev1.CreateFooWorkflowInput
2929

3030
progress float32
3131
status examplev1.Foo_Status
3232
}
3333

3434
// CreateFoo implements a CreateFoo workflow constructor on the shared Workflows struct
3535
// that initializes a new CreateFooWorkflow for each execution
36-
func (w *Workflows) CreateFoo(ctx workflow.Context, input *examplev1.CreateFooInput) (examplev1.CreateFooWorkflow, error) {
36+
func (w *Workflows) CreateFoo(ctx workflow.Context, input *examplev1.CreateFooWorkflowInput) (examplev1.CreateFooWorkflow, error) {
3737
return &CreateFooWorkflow{input, 0, examplev1.Foo_FOO_STATUS_CREATING}, nil
3838
}
3939

@@ -49,7 +49,7 @@ func (wf *CreateFooWorkflow) Execute(ctx workflow.Context) (*examplev1.CreateFoo
4949

5050
// execute Notify activity using generated helper
5151
err := examplev1.Notify(ctx, &examplev1.NotifyRequest{
52-
Message: fmt.Sprintf("creating foo resource (%s)", wf.Req.GetName()),
52+
Message: fmt.Sprintf("creating foo resource (%s)", wf.Req.GetRequestName()),
5353
})
5454
if err != nil {
5555
return nil, fmt.Errorf("error sending notification: %w", err)
@@ -62,7 +62,7 @@ func (wf *CreateFooWorkflow) Execute(ctx workflow.Context) (*examplev1.CreateFoo
6262

6363
return &examplev1.CreateFooResponse{
6464
Foo: &examplev1.Foo{
65-
Name: wf.Req.GetName(),
65+
Name: wf.Req.GetRequestName(),
6666
Status: wf.status,
6767
},
6868
}, nil

example/main_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,6 @@ func TestCreateFooStartWorkflowOptions(t *testing.T) {
5151
},
5252
)
5353
example := examplev1.NewExampleClient(c)
54-
_, err := example.CreateFooAsync(ctx, &examplev1.CreateFooRequest{Name: "bar"})
54+
_, err := example.CreateFooAsync(ctx, &examplev1.CreateFooInput{RequestName: "bar"})
5555
require.NoError(err)
5656
}

example/proto/example/v1/example.proto

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ syntax="proto3";
33
package example.v1;
44

55
import "google/protobuf/empty.proto";
6+
import "patch/go.proto";
67
import "temporal/v1/temporal.proto";
78

89
service Example {
@@ -55,8 +56,12 @@ service Example {
5556

5657
// CreateFooRequest describes the input to a CreateFoo workflow
5758
message CreateFooRequest {
59+
option (go.message).name = 'CreateFooInput';
60+
5861
// unique foo name
59-
string name = 1;
62+
string name = 1 [
63+
(go.field).name = 'RequestName'
64+
];
6065
}
6166

6267
// SampleWorkflowWithMutexResponse describes the output from a CreateFoo workflow

example/proto/patch/go.proto

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
syntax = "proto2";
2+
3+
//buf:lint:ignore PACKAGE_DIRECTORY_MATCH
4+
package go;
5+
6+
import "google/protobuf/descriptor.proto";
7+
8+
option go_package = "github.com/alta/protopatch/patch/gopb";
9+
10+
// Options represent Go-specific options for Protobuf messages, fields, oneofs, enums, or enum values.
11+
message Options {
12+
// The name option renames the generated Go identifier and related identifiers.
13+
// For a message, this renames the generated Go struct and nested messages or enums, if any.
14+
// For a message field, this renames the generated Go struct field and getter method.
15+
// For a oneof field, this renames the generated Go struct field, getter method, interface type, and wrapper types.
16+
// For an enum, this renames the generated Go type.
17+
// For an enum value, this renames the generated Go const.
18+
optional string name = 1;
19+
20+
// The embed option indicates the field should be embedded in the generated Go struct.
21+
// Only message types can be embedded. Oneof fields cannot be embedded.
22+
// See https://golang.org/ref/spec#Struct_types.
23+
optional bool embed = 2;
24+
25+
// The type option changes the generated field type.
26+
// All generated code assumes that this type is castable to the protocol buffer field type.
27+
optional string type = 3;
28+
29+
// The getter option renames the generated getter method (default: Get<Field>)
30+
// so a custom getter can be implemented in its place.
31+
optional string getter = 10; // TODO: implement this
32+
33+
// The tags option specifies additional struct tags which are appended a generated Go struct field.
34+
// This option may be specified on a message field or a oneof field.
35+
// The value should omit the enclosing backticks.
36+
optional string tags = 20;
37+
38+
// The stringer option renames a generated String() method (if any)
39+
// so a custom String() method can be implemented in its place.
40+
optional string stringer = 30; // TODO: implement for messages
41+
42+
// The stringer_name option is a deprecated alias for stringer.
43+
// It will be removed in a future version of this package.
44+
optional string stringer_name = 31;
45+
}
46+
47+
extend google.protobuf.MessageOptions {
48+
optional Options message = 7001;
49+
}
50+
51+
extend google.protobuf.FieldOptions {
52+
optional Options field = 7001;
53+
}
54+
55+
extend google.protobuf.OneofOptions {
56+
optional Options oneof = 7001;
57+
}
58+
59+
extend google.protobuf.EnumOptions {
60+
optional Options enum = 7001;
61+
}
62+
63+
extend google.protobuf.EnumValueOptions {
64+
optional Options value = 7001;
65+
}
66+
67+
// LintOptions represent options for linting a generated Go file.
68+
message LintOptions {
69+
// Set all to true if all generated Go symbols should be linted.
70+
// This option affects generated structs, struct fields, enum types, and value constants.
71+
optional bool all = 1;
72+
73+
// Set messages to true if message names should be linted.
74+
// This does not affect message fields.
75+
optional bool messages = 2;
76+
77+
// Set messages to true if message field names should be linted.
78+
// This does not affect message fields.
79+
optional bool fields = 3;
80+
81+
// Set enums to true if generated enum names should be linted.
82+
// This does not affect enum values.
83+
optional bool enums = 4;
84+
85+
// Set values to true if generated enum value constants should be linted.
86+
optional bool values = 5;
87+
88+
// Set extensions to true if generated extension names should be linted.
89+
optional bool extensions = 6;
90+
91+
// The initialisms option lets you specify strings that should not be generated as mixed-case,
92+
// Examples: ID, URL, HTTP, etc.
93+
repeated string initialisms = 10;
94+
}
95+
96+
extend google.protobuf.FileOptions {
97+
optional LintOptions lint = 7001;
98+
}

0 commit comments

Comments
 (0)