Skip to content
This repository has been archived by the owner on Jun 20, 2024. It is now read-only.

Commit

Permalink
Support enum values with prefix (#121)
Browse files Browse the repository at this point in the history
* feat: support enum trim prefix from value

* style: format code
  • Loading branch information
zbiljic authored Jun 29, 2022
1 parent 1e10cf8 commit fb6570f
Show file tree
Hide file tree
Showing 9 changed files with 123 additions and 43 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ These apply to specifically marked enums, giving you more finely-grained control

- [enums_as_constants](internal/converter/testdata/proto/ImportedEnum.proto): Encode ENUMs (and their annotations) as CONST
- [enums_as_strings_only](internal/converter/testdata/proto/OptionEnumsAsStringsOnly.proto): ENUM values are only strings (not the numeric counterparts)
- [enums_trim_prefix](internal/converter/testdata/proto/OptionEnumsTrimPrefix.proto): ENUM values have enum name prefix removed

### Field Options

Expand Down
26 changes: 23 additions & 3 deletions internal/converter/converter.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@ import (
"strings"

"github.com/alecthomas/jsonschema"
"github.com/chrusty/protoc-gen-jsonschema/internal/protos"
"github.com/iancoleman/strcase"
"github.com/sirupsen/logrus"
"github.com/xeipuuv/gojsonschema"
gengo "google.golang.org/protobuf/cmd/protoc-gen-go/internal_gengo"
"google.golang.org/protobuf/proto"
descriptor "google.golang.org/protobuf/types/descriptorpb"
plugin "google.golang.org/protobuf/types/pluginpb"

"github.com/chrusty/protoc-gen-jsonschema/internal/protos"
)

const (
Expand Down Expand Up @@ -52,6 +54,7 @@ type ConverterFlags struct {
EnforceOneOf bool
EnumsAsConstants bool
EnumsAsStringsOnly bool
EnumsTrimPrefix bool
KeepNewLinesInDescription bool
PrefixSchemaFilesWithPackage bool
UseJSONFieldnamesOnly bool
Expand Down Expand Up @@ -106,6 +109,8 @@ func (c *Converter) parseGeneratorParameters(parameters string) {
c.Flags.EnforceOneOf = true
case "enums_as_strings_only":
c.Flags.EnumsAsStringsOnly = true
case "enums_trim_prefix":
c.Flags.EnumsTrimPrefix = true
case "json_fieldnames":
c.Flags.UseJSONFieldnamesOnly = true
case "prefix_schema_files_with_package":
Expand Down Expand Up @@ -151,6 +156,11 @@ func (c *Converter) convertEnumType(enum *descriptor.EnumDescriptorProto, conver
if enumOptions.GetEnumsAsStringsOnly() {
converterFlags.EnumsAsStringsOnly = true
}

// ENUM values trim enum name prefix:
if enumOptions.GetEnumsTrimPrefix() {
converterFlags.EnumsTrimPrefix = true
}
}
}
}
Expand Down Expand Up @@ -182,6 +192,9 @@ func (c *Converter) convertEnumType(enum *descriptor.EnumDescriptorProto, conver
jsonSchemaType.OneOf = nil
}

// If we need to trim prefix from enum value
enumNamePrefix := fmt.Sprintf("%s_", strcase.ToScreamingSnake(*enum.Name))

// We have found an enum, append its values:
for _, value := range enum.Value {

Expand All @@ -191,17 +204,24 @@ func (c *Converter) convertEnumType(enum *descriptor.EnumDescriptorProto, conver
_, valueDescription = c.formatTitleAndDescription(nil, src)
}

valueName := value.GetName()

// If enum name prefix should be removed from enum value name:
if converterFlags.EnumsTrimPrefix {
valueName = strings.TrimPrefix(valueName, enumNamePrefix)
}

// If we're using constants for ENUMs then add these here, along with their title:
if converterFlags.EnumsAsConstants {
c.schemaVersion = versionDraft06 // Const requires draft-06
jsonSchemaType.OneOf = append(jsonSchemaType.OneOf, &jsonschema.Type{Extras: map[string]interface{}{"const": value.GetName()}, Description: valueDescription})
jsonSchemaType.OneOf = append(jsonSchemaType.OneOf, &jsonschema.Type{Extras: map[string]interface{}{"const": valueName}, Description: valueDescription})
if !converterFlags.EnumsAsStringsOnly {
jsonSchemaType.OneOf = append(jsonSchemaType.OneOf, &jsonschema.Type{Extras: map[string]interface{}{"const": value.GetNumber()}, Description: valueDescription})
}
}

// Add the values to the ENUM:
jsonSchemaType.Enum = append(jsonSchemaType.Enum, value.Name)
jsonSchemaType.Enum = append(jsonSchemaType.Enum, valueName)
if !converterFlags.EnumsAsStringsOnly {
jsonSchemaType.Enum = append(jsonSchemaType.Enum, value.Number)
}
Expand Down
10 changes: 10 additions & 0 deletions internal/converter/converter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,16 @@ func configureSampleProtos() map[string]sampleProto {
ObjectsToValidateFail: []string{testdata.OptionEnumsAsStringsOnlyFail},
ObjectsToValidatePass: []string{testdata.OptionEnumsAsStringsOnlyPass},
},
"OptionEnumsTrimPrefix": {
Flags: ConverterFlags{
EnumsTrimPrefix: true,
},
ExpectedJSONSchema: []string{testdata.OptionEnumsTrimPrefix},
FilesToGenerate: []string{"OptionEnumsTrimPrefix.proto"},
ProtoFileName: "OptionEnumsTrimPrefix.proto",
ObjectsToValidateFail: []string{testdata.OptionEnumsTrimPrefixFail},
ObjectsToValidatePass: []string{testdata.OptionEnumsTrimPrefixPass},
},
"OptionFileExtension": {
ExpectedJSONSchema: []string{testdata.OptionFileExtension},
ExpectedFileNames: []string{"OptionFileExtension.jsonschema"},
Expand Down
16 changes: 16 additions & 0 deletions internal/converter/testdata/option_enums_trim_prefix.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package testdata

const OptionEnumsTrimPrefix = `{
"$schema": "http://json-schema.org/draft-04/schema#",
"enum": [
"UNSPECIFIED",
"HTTP",
"HTTPS"
],
"type": "string",
"title": "Scheme"
}`

const OptionEnumsTrimPrefixPass = `"HTTP"`

const OptionEnumsTrimPrefixFail = `4`
14 changes: 14 additions & 0 deletions internal/converter/testdata/proto/OptionEnumsTrimPrefix.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
syntax = "proto3";
package samples;
import "options.proto";

enum Scheme {
option (protoc.gen.jsonschema.enum_options).enums_trim_prefix = true;

// for test
option (protoc.gen.jsonschema.enum_options).enums_as_strings_only = true;

SCHEME_UNSPECIFIED = 0;
SCHEME_HTTP = 1;
SCHEME_HTTPS = 2;
}
3 changes: 2 additions & 1 deletion internal/converter/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ import (
"strings"

"github.com/alecthomas/jsonschema"
"github.com/chrusty/protoc-gen-jsonschema/internal/protos"
"github.com/iancoleman/orderedmap"
"github.com/xeipuuv/gojsonschema"
"google.golang.org/protobuf/proto"
descriptor "google.golang.org/protobuf/types/descriptorpb"

"github.com/chrusty/protoc-gen-jsonschema/internal/protos"
)

var (
Expand Down
89 changes: 50 additions & 39 deletions internal/protos/options.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions jsonschemas/EnumOptions.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
"enums_as_strings_only": {
"type": "boolean",
"description": "Enums tagged with this will only provide string values as options (not their numerical equivalents):"
},
"enums_trim_prefix": {
"type": "boolean",
"description": "Enums tagged with this will have enum name prefix removed from values:"
}
},
"additionalProperties": true,
Expand Down
3 changes: 3 additions & 0 deletions options.proto
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ message EnumOptions {

// Enums tagged with this will only provide string values as options (not their numerical equivalents):
bool enums_as_strings_only = 2;

// Enums tagged with this will have enum name prefix removed from values:
bool enums_trim_prefix = 3;
}


Expand Down

0 comments on commit fb6570f

Please sign in to comment.