Skip to content

Commit

Permalink
Add option use-json-names to allow using json_name globally
Browse files Browse the repository at this point in the history
  • Loading branch information
mshibuya committed Dec 7, 2022
1 parent 34288dc commit 534268e
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 2 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ go install github.com/GoogleCloudPlatform/protoc-gen-bq-schema@latest
```

## Usage
protoc --bq-schema\_out=path/to/outdir \[--bq-schema_opt=single-message\] foo.proto
protoc --bq-schema\_out=path/to/outdir \[--bq-schema_opt=single-message,use-json-names\] foo.proto

`protoc` and `protoc-gen-bq-schema` commands must be found in $PATH.

Expand Down Expand Up @@ -72,6 +72,9 @@ The message `foo.Baz` is ignored because it doesn't have option `gen_bq_schema.b
`protoc --bq-schema_out=. --bq-schema_opt=single-message single_message.proto` will generate a file named `foo/single_message.schema`.
The message `foo.Baz` is also ignored because it is not the first message in the file.

`protoc --bq-schema_out=. --bq-schema_opt=use-json-names foo.proto` will generate a schema whose fields are named using `json_name`.
This is equivalent to tagging every message as `use_json_names = true` and provided for convenience.


### Support for PolicyTags
`protoc-gen-bq-schema` now supports [policyTags](https://cloud.google.com/bigquery/docs/column-level-security-intro).
Expand Down
18 changes: 17 additions & 1 deletion pkg/converter/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ var (
descriptor.FieldDescriptorProto_LABEL_REQUIRED: "REQUIRED",
descriptor.FieldDescriptorProto_LABEL_REPEATED: "REPEATED",
}

globallyUseJsonNames = false
)

// Field describes the schema of a field in BigQuery.
Expand Down Expand Up @@ -118,7 +120,7 @@ func convertField(
field := &Field{
Name: desc.GetName(),
}
if msgOpts.GetUseJsonNames() && desc.GetJsonName() != "" {
if (msgOpts.GetUseJsonNames() || globallyUseJsonNames) && desc.GetJsonName() != "" {
field.Name = desc.GetJsonName()
}

Expand Down Expand Up @@ -385,7 +387,21 @@ func handleSingleMessageOpt(file *descriptor.FileDescriptorProto, requestParam s
})
}

// handleUseJsonNamesOpt handles --bq-schema_opt=use-json-names in protoc params.
// providing that param tells protoc-gen-bq-schema to always use a field's json_name
// as the corresponding BigQuery column name.
// it is equivalent to setting the option use_json_name as true to every message.
func handleUseJsonNamesOpt(requestParam string) {
if !strings.Contains(requestParam, "use-json-names") {
return
}

globallyUseJsonNames = true
}

func Convert(req *plugin.CodeGeneratorRequest) (*plugin.CodeGeneratorResponse, error) {
handleUseJsonNamesOpt(req.GetParameter())

generateTargets := make(map[string]bool)
for _, file := range req.GetFileToGenerate() {
generateTargets[file] = true
Expand Down
34 changes: 34 additions & 0 deletions pkg/converter/plugin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -504,3 +504,37 @@ func TestExtraFields(t *testing.T) {
]`,
})
}

func TestUseJsonNamesOpt(t *testing.T) {
option := "use-json-names"
testConvert(t, `
file_to_generate: "foo.proto"
proto_file <
name: "foo.proto"
package: "example_package.nested"
message_type <
name: "FooProto"
field < name: "str" number: 1 type: TYPE_STRING label: LABEL_OPTIONAL json_name: "someJsonSpecificName" >
field <
name: "nested_message" number: 2 type: TYPE_MESSAGE label: LABEL_OPTIONAL
type_name: ".example_package.nested.FooProto.Nested" json_name: "nestedMessage"
>
nested_type <
name: "Nested"
field < name: "some_field" number: 1 type: TYPE_STRING label: LABEL_OPTIONAL json_name: "someField" >
>
options < [gen_bq_schema.bigquery_opts] <table_name: "foo_table"> >
>
>
`,
map[string]string{
"example_package/nested/foo_table.schema": `[
{ "name": "someJsonSpecificName", "type": "STRING", "mode": "NULLABLE" },
{
"name": "nestedMessage", "type": "RECORD", "mode": "NULLABLE",
"fields": [{ "name": "someField", "type": "STRING", "mode": "NULLABLE" }]
}
]`,
},
func(request *plugin.CodeGeneratorRequest) { request.Parameter = &option })
}

0 comments on commit 534268e

Please sign in to comment.