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

Commit

Permalink
Custom "ignore" option for fields you might not want (#71)
Browse files Browse the repository at this point in the history
* FieldOption to ignore

* New sample in the Makefile

* Few changes in the generated samples

* Feature flag to enable the ignore logic

* Unit tests

Co-authored-by: Chrusty <>
  • Loading branch information
chrusty authored Sep 4, 2021
1 parent 21f731b commit 0a23e0f
Show file tree
Hide file tree
Showing 13 changed files with 86 additions and 14 deletions.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ samples:
@PATH=./bin:$$PATH; protoc --jsonschema_out=jsonschemas --proto_path=${PROTO_PATH} ${PROTO_PATH}/Proto2Required.proto || echo "No messages found (Proto2Required.proto)"
@PATH=./bin:$$PATH; protoc --jsonschema_out=jsonschemas --proto_path=${PROTO_PATH} ${PROTO_PATH}/Proto2NestedMessage.proto || echo "No messages found (Proto2NestedMessage.proto)"
@PATH=./bin:$$PATH; protoc --jsonschema_out=jsonschemas --proto_path=${PROTO_PATH} ${PROTO_PATH}/GoogleValue.proto || echo "No messages found (GoogleValue.proto)"
@PATH=./bin:$$PATH; protoc --jsonschema_out=exclude_ignored_fields:jsonschemas -I. --proto_path=${PROTO_PATH} ${PROTO_PATH}/HiddenFields.proto || echo "No messages found (HiddenFields.proto)"
@PATH=./bin:$$PATH; protoc --jsonschema_out=enforce_oneof:jsonschemas --proto_path=${PROTO_PATH} ${PROTO_PATH}/OneOf.proto || echo "No messages found (OneOf.proto)"
@PATH=./bin:$$PATH; protoc --jsonschema_out=all_fields_required:jsonschemas --proto_path=${PROTO_PATH} ${PROTO_PATH}/Proto2NestedObject.proto || echo "No messages found (Proto2NestedObject.proto)"
@PATH=./bin:$$PATH; protoc -I /usr/include --jsonschema_out=jsonschemas --proto_path=${PROTO_PATH} ${PROTO_PATH}/WellKnown.proto || echo "No messages found (WellKnown.proto)"
Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,9 @@ protoc \ # The protobuf compiler
|`debug`| Enable debug logging |
|`disallow_additional_properties`| Disallow additional properties in schema |
|`disallow_bigints_as_strings`| Disallow big integers as strings |
|`enforce_oneof` | Interpret Proto "oneOf" clauses |
|`json_fieldnames` | Use JSON field names only |
|`enforce_oneof`| Interpret Proto "oneOf" clauses |
|`exclude_ignored_fields`| Omit fields marked with the custom "ignore" option |
|`json_fieldnames`| Use JSON field names only |
|`prefix_schema_files_with_package`| Prefix the output filename with package |
|`proto_and_json_fieldnames`| Use proto and JSON field names |

Expand Down
18 changes: 12 additions & 6 deletions internal/converter/converter.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,17 @@ import (
)

const (
messageDelimiter = "+"
ignoredFieldOption = "50505:1"
messageDelimiter = "+"
)

// Converter is everything you need to convert protos to JSONSchemas:
type Converter struct {
Flags ConverterFlags
logger *logrus.Logger
sourceInfo *sourceCodeInfo
messageTargets []string
Flags ConverterFlags
ignoredFieldOption string
logger *logrus.Logger
sourceInfo *sourceCodeInfo
messageTargets []string
}

// ConverterFlags control the behaviour of the converter:
Expand All @@ -35,6 +37,7 @@ type ConverterFlags struct {
DisallowAdditionalProperties bool
DisallowBigIntsAsStrings bool
EnforceOneOf bool
ExcludeIgnoredFields bool
PrefixSchemaFilesWithPackage bool
UseJSONFieldnamesOnly bool
UseProtoAndJSONFieldNames bool
Expand All @@ -43,7 +46,8 @@ type ConverterFlags struct {
// New returns a configured *Converter:
func New(logger *logrus.Logger) *Converter {
return &Converter{
logger: logger,
ignoredFieldOption: ignoredFieldOption,
logger: logger,
}
}

Expand Down Expand Up @@ -82,6 +86,8 @@ func (c *Converter) parseGeneratorParameters(parameters string) {
c.Flags.DisallowBigIntsAsStrings = true
case "enforce_oneof":
c.Flags.EnforceOneOf = true
case "exclude_ignored_fields":
c.Flags.ExcludeIgnoredFields = true
case "json_fieldnames":
c.Flags.UseJSONFieldnamesOnly = true
case "prefix_schema_files_with_package":
Expand Down
7 changes: 7 additions & 0 deletions internal/converter/converter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,12 @@ func configureSampleProtos() map[string]sampleProto {
FilesToGenerate: []string{"OneOf.proto"},
ProtoFileName: "OneOf.proto",
},
"HiddenFields": {
Flags: ConverterFlags{ExcludeIgnoredFields: true},
ExpectedJSONSchema: []string{testdata.HiddenFields},
FilesToGenerate: []string{"options.proto", "HiddenFields.proto"},
ProtoFileName: "HiddenFields.proto",
},
}
}

Expand All @@ -284,6 +290,7 @@ func mustReadProtoFiles(t *testing.T, includePath string, filenames ...string) *
args = append(args, "--descriptor_set_out=/dev/stdout")
args = append(args, "--include_source_info")
args = append(args, "--include_imports")
args = append(args, "-I../../")
args = append(args, "--proto_path="+includePath)
args = append(args, filenames...)
cmd := exec.Command(protocBinary, args...)
Expand Down
15 changes: 15 additions & 0 deletions internal/converter/testdata/hidden_fields.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package testdata

const HiddenFields = `{
"$schema": "http://json-schema.org/draft-04/schema#",
"properties": {
"visible1": {
"type": "string"
},
"visible2": {
"type": "string"
}
},
"additionalProperties": true,
"type": "object"
}`
10 changes: 10 additions & 0 deletions internal/converter/testdata/proto/HiddenFields.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
syntax = "proto3";
package samples;
import "options.proto";

message HiddenFields {
string visible1 = 1 [(protoc.gen.jsonschema.ignore) = false];
string visible2 = 2;
string hidden1 = 3 [(protoc.gen.jsonschema.ignore) = true];
string hidden2 = 4 [deprecated = true, (protoc.gen.jsonschema.ignore) = true];
}
7 changes: 7 additions & 0 deletions internal/converter/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,13 @@ func (c *Converter) recursiveConvertMessageType(curPkg *ProtoPackage, msg *descr

c.logger.WithField("message_str", proto.MarshalTextString(msg)).Trace("Converting message")
for _, fieldDesc := range msg.GetField() {

// Look for our custom "ignore" field-option (and hope that nobody else happens to be using our number):
if c.Flags.ExcludeIgnoredFields && strings.Contains(fieldDesc.GetOptions().String(), c.ignoredFieldOption) {
c.logger.WithField("field_name", fieldDesc.GetName()).WithField("message_name", msg.GetName()).Debug("Omitting ignored field")
continue
}

recursedJSONSchemaType, err := c.convertField(curPkg, fieldDesc, msg, duplicatedMessages)
if err != nil {
c.logger.WithError(err).WithField("field_name", fieldDesc.GetName()).WithField("message_name", msg.GetName()).Error("Failed to convert field")
Expand Down
3 changes: 2 additions & 1 deletion jsonschemas/Enumception.jsonschema
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,14 @@
},
"payload": {
"$ref": "samples.PayloadMessage",
"additionalProperties": true
"additionalProperties": false
},
"payloads": {
"items": {
"$schema": "http://json-schema.org/draft-04/schema#",
"$ref": "samples.PayloadMessage"
},
"additionalProperties": false,
"type": "array"
},
"importedEnum": {
Expand Down
3 changes: 2 additions & 1 deletion jsonschemas/GoogleValue.jsonschema
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
{
"type": "string"
}
]
],
"description": "`Value` represents a dynamically typed value which can be either\n null, a number, a string, a boolean, a recursive struct value, or a\n list of values. A producer of value is expected to set one of that\n variants, absence of any variant indicates an error.\n\n The JSON representation for `Value` is JSON value."
}
},
"additionalProperties": true,
Expand Down
13 changes: 13 additions & 0 deletions jsonschemas/HiddenFields.jsonschema
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"$schema": "http://json-schema.org/draft-04/schema#",
"properties": {
"visible1": {
"type": "string"
},
"visible2": {
"type": "string"
}
},
"additionalProperties": true,
"type": "object"
}
2 changes: 1 addition & 1 deletion jsonschemas/NestedMessage.jsonschema
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
]
}
},
"additionalProperties": true,
"additionalProperties": false,
"type": "object"
},
"description": {
Expand Down
9 changes: 6 additions & 3 deletions jsonschemas/WellKnown.jsonschema
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,16 @@
},
"list_of_integers": {
"items": {
"type": "integer"
"type": "integer",
"description": "Wrapper message for `int32`.\n\n The JSON representation for `Int32Value` is JSON number."
},
"type": "array"
},
"duration": {
"additionalProperties": true,
"type": "string"
"pattern": "^([0-9]+\\.?[0-9]*|\\.[0-9]+)s$",
"type": "string",
"description": "This is a duration:",
"format": "regex"
}
},
"additionalProperties": true,
Expand Down
7 changes: 7 additions & 0 deletions options.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
syntax = "proto3";
package protoc.gen.jsonschema;
import "google/protobuf/descriptor.proto";

extend google.protobuf.FieldOptions {
optional bool ignore = 50505;
}

0 comments on commit 0a23e0f

Please sign in to comment.