Skip to content

Commit

Permalink
fix: Fix bug circular dependent message (#9)
Browse files Browse the repository at this point in the history
  • Loading branch information
uanid authored Nov 8, 2024
1 parent 8e90b70 commit 00cc2ce
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 10 deletions.
23 changes: 13 additions & 10 deletions pkg/modules/2_backend_optimizer.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@ func NewOptimizerImpl(pluginOptions *proto.PluginOptions) *OptimizerImpl {
return &OptimizerImpl{schemaByRef: jsonschema.NewOrderedSchemaMap(), pluginOptions: pluginOptions}
}

const refCountKey = "refCount"
const linkedFromEntrypoint = "linkedFromEntrypoint"

func (o *OptimizerImpl) Optimize(registry *jsonschema.Registry, entrypointMessage pgs.Message) {
entrypointSchemaRef := toRefId(entrypointMessage)
entrypointSchema := registry.GetSchema(entrypointSchemaRef.String())

o.increaseSchemaRefCount(registry, entrypointSchemaRef.String())
o.checkAndMarkSchemaToVisitable(registry, entrypointSchemaRef.String())
o.visitSchema(registry, entrypointSchema)

o.optimizeDefinitions(registry)
Expand All @@ -39,9 +39,9 @@ func (o *OptimizerImpl) optimizeDefinitions(registry *jsonschema.Registry) {
var deleteKeys []string
for _, key := range registry.GetKeys() {
schema := registry.GetSchema(key)
if schema.GetExtrasItem(refCountKey) == nil {
if schema.GetExtrasItem(linkedFromEntrypoint) == nil {
deleteKeys = append(deleteKeys, key)
} else if schema.GetExtrasItem(refCountKey).(int) == 0 {
} else if schema.GetExtrasItem(linkedFromEntrypoint).(bool) == false {
deleteKeys = append(deleteKeys, key)
}
}
Expand All @@ -66,17 +66,19 @@ func (o *OptimizerImpl) getEntrypointMessage(messages []pgs.Message, fileOptions
return nil
}

func (o *OptimizerImpl) increaseSchemaRefCount(registry *jsonschema.Registry, ref string) {
// return true if first visit to schema
func (o *OptimizerImpl) checkAndMarkSchemaToVisitable(registry *jsonschema.Registry, ref string) bool {
schema := registry.GetSchema(ref)
if schema == nil {
panic(fmt.Sprintf("schema not found: %s", ref))
}

rawValue := schema.GetExtrasItem(refCountKey)
rawValue := schema.GetExtrasItem(linkedFromEntrypoint)
if rawValue == nil {
schema.SetExtrasItem(refCountKey, int(1))
schema.SetExtrasItem(linkedFromEntrypoint, true)
return true
} else {
schema.SetExtrasItem(refCountKey, rawValue.(int)+1)
return false
}
}

Expand All @@ -86,8 +88,9 @@ func (o *OptimizerImpl) visitSchema(registry *jsonschema.Registry, schema *jsons
}

if !schema.Ref.IsEmpty() {
o.increaseSchemaRefCount(registry, schema.Ref.String())
o.visitSchema(registry, registry.GetSchema(schema.Ref.String()))
if o.checkAndMarkSchemaToVisitable(registry, schema.Ref.String()) {
o.visitSchema(registry, registry.GetSchema(schema.Ref.String()))
}
}
o.visitSchemaMap(registry, schema.Definitions)

Expand Down
2 changes: 2 additions & 0 deletions testdata/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ proto-optional optional이 있다면 required에서 빠지는지 테스트
proto-message message가 object로 잘 전환되는지 테스트
proto-circular-dependent 순환 의존성이 있는 메시지를 잘 전환하는지 테스트
proto-enum enum이 enum으로 잘 전환되는지 테스트
plugin-preserve-field-name-false json_name이 잘 적용되는지 테스트
Expand Down
23 changes: 23 additions & 0 deletions testdata/cases/proto-circular-dependent/test.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
syntax = "proto3";

package tests;

import "jsonschema.proto";

option (pubg.jsonschema.file) = {entrypoint_message: "Values"};

message Values {
SelfReference entry = 1;
}

//message CircularDependentTwoDepth {
// CircularDependentTwoDepth0 child = 1;
//}
//
//message CircularDependentTwoDepth0 {
// CircularDependentTwoDepth parent = 1;
//}

message SelfReference {
SelfReference self = 1;
}
36 changes: 36 additions & 0 deletions testdata/cases/proto-circular-dependent/test.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$ref": "#/$defs/.tests.Values",
"$defs": {
".tests.Values": {
"properties": {
"entry": {
"$ref": "#/$defs/.tests.Values.entry"
}
},
"type": "object",
"required": [
"entry"
]
},
".tests.Values.entry": {
"$ref": "#/$defs/.tests.SelfReference"
},
".tests.SelfReference": {
"properties": {
"self": {
"$ref": "#/$defs/.tests.SelfReference.self"
}
},
"type": "object",
"required": [
"self"
],
"description": "message CircularDependentTwoDepth {\n CircularDependentTwoDepth0 child = 1;\n}\n\nmessage CircularDependentTwoDepth0 {\n CircularDependentTwoDepth parent = 1;\n}"
},
".tests.SelfReference.self": {
"$ref": "#/$defs/.tests.SelfReference"
}
},
"type": "object"
}
11 changes: 11 additions & 0 deletions testdata/cases/proto-circular-dependent/test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
name: "proto-circular-dependent"
description: "Test for circular dependent message in proto file"

inputFiles: ["test.proto"]
inputParameters: {}

expectResultFiles: ["test.schema.json"]
expectResultIsNull: false
expectFail: false

expectedBehaviorDescription: ""

0 comments on commit 00cc2ce

Please sign in to comment.