This is an automated email from the ASF dual-hosted git repository.
AlexStocks pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/dubbo-go.git
The following commit(s) were added to refs/heads/develop by this push:
new 115af01da fix(openapi): generate enum components and map value schemas
(#3609)
115af01da is described below
commit 115af01da805090d153f68cfd4974dc41e69fdcc
Author: XiaoFei <[email protected]>
AuthorDate: Sat Aug 8 18:31:04 2026 +0800
fix(openapi): generate enum components and map value schemas (#3609)
* fix(openapi): generate enum components and map value schemas
* fix(openapi): cover map reference values and error schema collisions
---
.../protoc-gen-triple-openapi/example/greet.proto | 4 +
.../example/greet.triple.openapi.json | 69 +++++++++++++-
.../example/greet.triple.openapi.yaml | 48 ++++++++++
.../internal/converter/components.go | 11 ++-
.../internal/converter/convert.go | 11 ++-
.../internal/converter/convert_test.go | 105 +++++++++++++++++++++
.../internal/converter/schema/schema.go | 40 +++++---
.../internal/converter/schema/util.go | 23 ++++-
8 files changed, 289 insertions(+), 22 deletions(-)
diff --git a/tools/protoc-gen-triple-openapi/example/greet.proto
b/tools/protoc-gen-triple-openapi/example/greet.proto
index 3db26d2d7..897fe6630 100644
--- a/tools/protoc-gen-triple-openapi/example/greet.proto
+++ b/tools/protoc-gen-triple-openapi/example/greet.proto
@@ -32,6 +32,10 @@ message GreetRequest {
map<string, string> metadata = 3;
GreetingType type = 4;
GreetProfile profile = 5;
+ repeated GreetingType types = 6;
+ repeated GreetProfile profiles = 7;
+ map<string, GreetProfile> profile_metadata = 8;
+ map<string, GreetingType> type_metadata = 9;
}
message GreetProfile {
diff --git a/tools/protoc-gen-triple-openapi/example/greet.triple.openapi.json
b/tools/protoc-gen-triple-openapi/example/greet.triple.openapi.json
index 8a322723f..289675c87 100644
--- a/tools/protoc-gen-triple-openapi/example/greet.triple.openapi.json
+++ b/tools/protoc-gen-triple-openapi/example/greet.triple.openapi.json
@@ -141,7 +141,10 @@
},
"metadata": {
"type": "object",
- "title": "metadata"
+ "title": "metadata",
+ "additionalProperties": {
+ "type": "string"
+ }
},
"type": {
"title": "type",
@@ -150,6 +153,34 @@
"profile": {
"title": "profile",
"$ref": "#/components/schemas/greet.GreetProfile"
+ },
+ "types": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/greet.GreetingType"
+ },
+ "title": "types"
+ },
+ "profiles": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/greet.GreetProfile"
+ },
+ "title": "profiles"
+ },
+ "profileMetadata": {
+ "type": "object",
+ "title": "profile_metadata",
+ "additionalProperties": {
+ "$ref": "#/components/schemas/greet.GreetProfile"
+ }
+ },
+ "typeMetadata": {
+ "type": "object",
+ "title": "type_metadata",
+ "additionalProperties": {
+ "$ref": "#/components/schemas/greet.GreetingType"
+ }
}
},
"title": "GreetRequest"
@@ -168,6 +199,34 @@
},
"title": "MetadataEntry"
},
+ "greet.GreetRequest.ProfileMetadataEntry": {
+ "type": "object",
+ "properties": {
+ "key": {
+ "type": "string",
+ "title": "key"
+ },
+ "value": {
+ "title": "value",
+ "$ref": "#/components/schemas/greet.GreetProfile"
+ }
+ },
+ "title": "ProfileMetadataEntry"
+ },
+ "greet.GreetRequest.TypeMetadataEntry": {
+ "type": "object",
+ "properties": {
+ "key": {
+ "type": "string",
+ "title": "key"
+ },
+ "value": {
+ "title": "value",
+ "$ref": "#/components/schemas/greet.GreetingType"
+ }
+ },
+ "title": "TypeMetadataEntry"
+ },
"greet.GreetResponse": {
"type": "object",
"properties": {
@@ -198,6 +257,14 @@
},
"title": "GreetUserResponse"
},
+ "greet.GreetingType": {
+ "type": "string",
+ "title": "GreetingType",
+ "enum": [
+ "GREETING_TYPE_UNSPECIFIED",
+ "GREETING_TYPE_FORMAL"
+ ]
+ },
"ErrorResponse": {
"type": "object",
"properties": {
diff --git a/tools/protoc-gen-triple-openapi/example/greet.triple.openapi.yaml
b/tools/protoc-gen-triple-openapi/example/greet.triple.openapi.yaml
index a56c7ccb9..975cf78a1 100644
--- a/tools/protoc-gen-triple-openapi/example/greet.triple.openapi.yaml
+++ b/tools/protoc-gen-triple-openapi/example/greet.triple.openapi.yaml
@@ -90,12 +90,34 @@ components:
metadata:
type: object
title: metadata
+ additionalProperties:
+ type: string
type:
title: type
$ref: '#/components/schemas/greet.GreetingType'
profile:
title: profile
$ref: '#/components/schemas/greet.GreetProfile'
+ types:
+ type: array
+ items:
+ $ref: '#/components/schemas/greet.GreetingType'
+ title: types
+ profiles:
+ type: array
+ items:
+ $ref: '#/components/schemas/greet.GreetProfile'
+ title: profiles
+ profileMetadata:
+ type: object
+ title: profile_metadata
+ additionalProperties:
+ $ref: '#/components/schemas/greet.GreetProfile'
+ typeMetadata:
+ type: object
+ title: type_metadata
+ additionalProperties:
+ $ref: '#/components/schemas/greet.GreetingType'
title: GreetRequest
greet.GreetRequest.MetadataEntry:
type: object
@@ -107,6 +129,26 @@ components:
type: string
title: value
title: MetadataEntry
+ greet.GreetRequest.ProfileMetadataEntry:
+ type: object
+ properties:
+ key:
+ type: string
+ title: key
+ value:
+ title: value
+ $ref: '#/components/schemas/greet.GreetProfile'
+ title: ProfileMetadataEntry
+ greet.GreetRequest.TypeMetadataEntry:
+ type: object
+ properties:
+ key:
+ type: string
+ title: key
+ value:
+ title: value
+ $ref: '#/components/schemas/greet.GreetingType'
+ title: TypeMetadataEntry
greet.GreetResponse:
type: object
properties:
@@ -128,6 +170,12 @@ components:
type: string
title: greeting
title: GreetUserResponse
+ greet.GreetingType:
+ type: string
+ title: GreetingType
+ enum:
+ - GREETING_TYPE_UNSPECIFIED
+ - GREETING_TYPE_FORMAL
ErrorResponse:
type: object
properties:
diff --git a/tools/protoc-gen-triple-openapi/internal/converter/components.go
b/tools/protoc-gen-triple-openapi/internal/converter/components.go
index 2a2bca07c..a10256c11 100644
--- a/tools/protoc-gen-triple-openapi/internal/converter/components.go
+++ b/tools/protoc-gen-triple-openapi/internal/converter/components.go
@@ -29,12 +29,17 @@ import (
"dubbo.apache.org/dubbo-go/v3/tools/protoc-gen-triple-openapi/internal/converter/schema"
)
-func generateComponents(fd protoreflect.FileDescriptor)
(*openapimodel.Components, error) {
+func generateComponents(fd protoreflect.FileDescriptor)
(*openapimodel.Components, string, error) {
components := &openapimodel.Components{
Schemas: schema.GenerateFileSchemas(fd),
}
// triple error component
+ errorResponseSchemaID := "ErrorResponse"
+ if components.Schemas.GetOrZero(errorResponseSchemaID) != nil {
+ // A hyphen cannot occur in a protobuf full name, so this ID
cannot collide.
+ errorResponseSchemaID = "Triple-ErrorResponse"
+ }
errorResponseProps := orderedmap.New[string, *base.SchemaProxy]()
errorResponseProps.Set("status", base.CreateSchemaProxy(&base.Schema{
Description: "The status code.",
@@ -44,12 +49,12 @@ func generateComponents(fd protoreflect.FileDescriptor)
(*openapimodel.Component
Description: "A developer-facing error message.",
Type: []string{"string"},
}))
- components.Schemas.Set("ErrorResponse",
base.CreateSchemaProxy(&base.Schema{
+ components.Schemas.Set(errorResponseSchemaID,
base.CreateSchemaProxy(&base.Schema{
Title: "ErrorResponse",
Description: `Error type returned by triple:
https://cn.dubbo.apache.org/zh-cn/overview/reference/protocols/triple-spec/`,
Properties: errorResponseProps,
Type: []string{"object"},
}))
- return components, nil
+ return components, errorResponseSchemaID, nil
}
diff --git a/tools/protoc-gen-triple-openapi/internal/converter/convert.go
b/tools/protoc-gen-triple-openapi/internal/converter/convert.go
index 7bb59b59a..f663eb682 100644
--- a/tools/protoc-gen-triple-openapi/internal/converter/convert.go
+++ b/tools/protoc-gen-triple-openapi/internal/converter/convert.go
@@ -116,7 +116,8 @@ func convert(req *pluginpb.CodeGeneratorRequest)
(*pluginpb.CodeGeneratorRespons
})
// handle openapi components
- doc.Components, err = generateComponents(fd)
+ errorResponseSchemaID := ""
+ doc.Components, errorResponseSchemaID, err =
generateComponents(fd)
if err != nil {
return nil, err
}
@@ -166,10 +167,10 @@ func convert(req *pluginpb.CodeGeneratorRequest)
(*pluginpb.CodeGeneratorRespons
})
// status code 400
- codeMap.Set(constant.StatusCode400,
newErrorResponse(constant.StatusCode400Description))
+ codeMap.Set(constant.StatusCode400,
newErrorResponse(constant.StatusCode400Description, errorResponseSchemaID))
// status code 500
- codeMap.Set(constant.StatusCode500,
newErrorResponse(constant.StatusCode500Description))
+ codeMap.Set(constant.StatusCode500,
newErrorResponse(constant.StatusCode500Description, errorResponseSchemaID))
operation.Responses = &openapimodel.Responses{
Codes: codeMap,
@@ -225,8 +226,8 @@ func formatOpenapiDoc(opts options.Options, doc
*openapimodel.Document) (string,
}
}
-func newErrorResponse(description string) *openapimodel.Response {
- responseSchema :=
base.CreateSchemaProxyRef(constant.OpenAPIDocComponentsSchemaSuffix +
"ErrorResponse")
+func newErrorResponse(description, schemaID string) *openapimodel.Response {
+ responseSchema :=
base.CreateSchemaProxyRef(constant.OpenAPIDocComponentsSchemaSuffix + schemaID)
responseMediaType := makeMediaTypes(responseSchema)
return &openapimodel.Response{
Description: description,
diff --git a/tools/protoc-gen-triple-openapi/internal/converter/convert_test.go
b/tools/protoc-gen-triple-openapi/internal/converter/convert_test.go
index 2278ac1f9..d2ba3f71a 100644
--- a/tools/protoc-gen-triple-openapi/internal/converter/convert_test.go
+++ b/tools/protoc-gen-triple-openapi/internal/converter/convert_test.go
@@ -122,6 +122,10 @@ func greetRequest(format string)
*pluginpb.CodeGeneratorRequest {
field("metadata",
"metadata", 3, descriptorpb.FieldDescriptorProto_LABEL_REPEATED,
descriptorpb.FieldDescriptorProto_TYPE_MESSAGE,
".greet.GreetRequest.MetadataEntry"),
field("type", "type",
4, descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL,
descriptorpb.FieldDescriptorProto_TYPE_ENUM, ".greet.GreetingType"),
field("profile",
"profile", 5, descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL,
descriptorpb.FieldDescriptorProto_TYPE_MESSAGE, ".greet.GreetProfile"),
+ field("types", "types",
6, descriptorpb.FieldDescriptorProto_LABEL_REPEATED,
descriptorpb.FieldDescriptorProto_TYPE_ENUM, ".greet.GreetingType"),
+ field("profiles",
"profiles", 7, descriptorpb.FieldDescriptorProto_LABEL_REPEATED,
descriptorpb.FieldDescriptorProto_TYPE_MESSAGE, ".greet.GreetProfile"),
+
field("profile_metadata", "profileMetadata", 8,
descriptorpb.FieldDescriptorProto_LABEL_REPEATED,
descriptorpb.FieldDescriptorProto_TYPE_MESSAGE,
".greet.GreetRequest.ProfileMetadataEntry"),
+ field("type_metadata",
"typeMetadata", 9, descriptorpb.FieldDescriptorProto_LABEL_REPEATED,
descriptorpb.FieldDescriptorProto_TYPE_MESSAGE,
".greet.GreetRequest.TypeMetadataEntry"),
},
NestedType:
[]*descriptorpb.DescriptorProto{
{
@@ -132,6 +136,22 @@ func greetRequest(format string)
*pluginpb.CodeGeneratorRequest {
},
Options:
&descriptorpb.MessageOptions{MapEntry: proto.Bool(true)},
},
+ {
+ Name:
proto.String("ProfileMetadataEntry"),
+ Field:
[]*descriptorpb.FieldDescriptorProto{
+
field("key", "key", 1, descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL,
descriptorpb.FieldDescriptorProto_TYPE_STRING, ""),
+
field("value", "value", 2, descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL,
descriptorpb.FieldDescriptorProto_TYPE_MESSAGE, ".greet.GreetProfile"),
+ },
+ Options:
&descriptorpb.MessageOptions{MapEntry: proto.Bool(true)},
+ },
+ {
+ Name:
proto.String("TypeMetadataEntry"),
+ Field:
[]*descriptorpb.FieldDescriptorProto{
+
field("key", "key", 1, descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL,
descriptorpb.FieldDescriptorProto_TYPE_STRING, ""),
+
field("value", "value", 2, descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL,
descriptorpb.FieldDescriptorProto_TYPE_ENUM, ".greet.GreetingType"),
+ },
+ Options:
&descriptorpb.MessageOptions{MapEntry: proto.Bool(true)},
+ },
},
},
{
@@ -173,6 +193,91 @@ func greetRequest(format string)
*pluginpb.CodeGeneratorRequest {
}
}
+func TestConvertErrorResponseEnumCollision(t *testing.T) {
+ request := &pluginpb.CodeGeneratorRequest{
+ FileToGenerate: []string{"collision.proto"},
+ Parameter: proto.String("format=yaml"),
+ ProtoFile: []*descriptorpb.FileDescriptorProto{{
+ Name: proto.String("collision.proto"),
+ Syntax: proto.String("proto3"),
+ EnumType: []*descriptorpb.EnumDescriptorProto{{
+ Name: proto.String("ErrorResponse"),
+ Value:
[]*descriptorpb.EnumValueDescriptorProto{{Name: proto.String("UNKNOWN"),
Number: proto.Int32(0)}},
+ }},
+ MessageType: []*descriptorpb.DescriptorProto{
+ {Name: proto.String("Request"), Field:
[]*descriptorpb.FieldDescriptorProto{field("state", "state", 1,
descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL,
descriptorpb.FieldDescriptorProto_TYPE_ENUM, ".ErrorResponse")}},
+ {Name: proto.String("Response")},
+ },
+ Service: []*descriptorpb.ServiceDescriptorProto{{
+ Name: proto.String("Service"),
+ Method:
[]*descriptorpb.MethodDescriptorProto{{Name: proto.String("Call"), InputType:
proto.String(".Request"), OutputType: proto.String(".Response")}},
+ }},
+ }},
+ }
+
+ response, err := convert(request)
+ if err != nil {
+ t.Fatalf("convert() error = %v", err)
+ }
+ got := response.File[0].GetContent()
+ for _, want := range []string{
+ "state:\n title: state\n $ref:
'#/components/schemas/ErrorResponse'",
+ "ErrorResponse:\n type: string\n title:
ErrorResponse\n enum:\n - UNKNOWN",
+ "Triple-ErrorResponse:\n type: object",
+ "$ref: '#/components/schemas/Triple-ErrorResponse'",
+ } {
+ if !strings.Contains(got, want) {
+ t.Errorf("generated OpenAPI does not contain %q\n%s",
want, got)
+ }
+ }
+}
+
+func TestConvertErrorResponseMessageCollision(t *testing.T) {
+ request := &pluginpb.CodeGeneratorRequest{
+ FileToGenerate: []string{"collision.proto"},
+ Parameter: proto.String("format=yaml"),
+ ProtoFile: []*descriptorpb.FileDescriptorProto{{
+ Name: proto.String("collision.proto"),
+ Syntax: proto.String("proto3"),
+ MessageType: []*descriptorpb.DescriptorProto{
+ {
+ Name: proto.String("ErrorResponse"),
+ Field:
[]*descriptorpb.FieldDescriptorProto{
+ field("detail", "detail", 1,
descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL,
descriptorpb.FieldDescriptorProto_TYPE_STRING, ""),
+ },
+ },
+ {
+ Name: proto.String("Request"),
+ Field:
[]*descriptorpb.FieldDescriptorProto{
+ field("error", "error", 1,
descriptorpb.FieldDescriptorProto_LABEL_OPTIONAL,
descriptorpb.FieldDescriptorProto_TYPE_MESSAGE, ".ErrorResponse"),
+ },
+ },
+ {Name: proto.String("Response")},
+ },
+ Service: []*descriptorpb.ServiceDescriptorProto{{
+ Name: proto.String("Service"),
+ Method:
[]*descriptorpb.MethodDescriptorProto{{Name: proto.String("Call"), InputType:
proto.String(".Request"), OutputType: proto.String(".Response")}},
+ }},
+ }},
+ }
+
+ response, err := convert(request)
+ if err != nil {
+ t.Fatalf("convert() error = %v", err)
+ }
+ got := response.File[0].GetContent()
+ for _, want := range []string{
+ "error:\n title: error\n $ref:
'#/components/schemas/ErrorResponse'",
+ "ErrorResponse:\n type: object\n properties:\n
detail:",
+ "Triple-ErrorResponse:\n type: object",
+ "$ref: '#/components/schemas/Triple-ErrorResponse'",
+ } {
+ if !strings.Contains(got, want) {
+ t.Errorf("generated OpenAPI does not contain %q\n%s",
want, got)
+ }
+ }
+}
+
func field(name, jsonName string, number int32, label
descriptorpb.FieldDescriptorProto_Label, kind
descriptorpb.FieldDescriptorProto_Type, typeName string)
*descriptorpb.FieldDescriptorProto {
fd := &descriptorpb.FieldDescriptorProto{
Name: proto.String(name),
diff --git
a/tools/protoc-gen-triple-openapi/internal/converter/schema/schema.go
b/tools/protoc-gen-triple-openapi/internal/converter/schema/schema.go
index c7b5f9aee..22ee710e6 100644
--- a/tools/protoc-gen-triple-openapi/internal/converter/schema/schema.go
+++ b/tools/protoc-gen-triple-openapi/internal/converter/schema/schema.go
@@ -30,7 +30,8 @@ import (
func GenerateFileSchemas(tt protoreflect.FileDescriptor)
*orderedmap.Map[string, *base.SchemaProxy] {
messages := make(map[protoreflect.MessageDescriptor]struct{})
- collectMessages(tt, messages)
+ enums := make(map[protoreflect.EnumDescriptor]struct{})
+ collectMessages(tt, messages, enums)
schemas := orderedmap.New[string, *base.SchemaProxy]()
@@ -51,27 +52,40 @@ func GenerateFileSchemas(tt protoreflect.FileDescriptor)
*orderedmap.Map[string,
}
}
+ sortedEnums := make([]protoreflect.EnumDescriptor, 0, len(enums))
+ for enum := range enums {
+ sortedEnums = append(sortedEnums, enum)
+ }
+ sort.Slice(sortedEnums, func(i, j int) bool {
+ return sortedEnums[i].FullName() < sortedEnums[j].FullName()
+ })
+
+ for _, enum := range sortedEnums {
+ id, schema := enumToSchema(enum)
+ schemas.Set(id, base.CreateSchemaProxy(schema))
+ }
+
return schemas
}
-func collectMessages(fd protoreflect.FileDescriptor, messages
map[protoreflect.MessageDescriptor]struct{}) {
+func collectMessages(fd protoreflect.FileDescriptor, messages
map[protoreflect.MessageDescriptor]struct{}, enums
map[protoreflect.EnumDescriptor]struct{}) {
services := fd.Services()
for i := 0; i < services.Len(); i++ {
service := services.Get(i)
methods := service.Methods()
for j := 0; j < methods.Len(); j++ {
method := methods.Get(j)
- collectMethodMessages(method, messages)
+ collectMethodMessages(method, messages, enums)
}
}
}
-func collectMethodMessages(md protoreflect.MethodDescriptor, messages
map[protoreflect.MessageDescriptor]struct{}) {
- collectMessage(md.Input(), messages)
- collectMessage(md.Output(), messages)
+func collectMethodMessages(md protoreflect.MethodDescriptor, messages
map[protoreflect.MessageDescriptor]struct{}, enums
map[protoreflect.EnumDescriptor]struct{}) {
+ collectMessage(md.Input(), messages, enums)
+ collectMessage(md.Output(), messages, enums)
}
-func collectMessage(md protoreflect.MessageDescriptor, messages
map[protoreflect.MessageDescriptor]struct{}) {
+func collectMessage(md protoreflect.MessageDescriptor, messages
map[protoreflect.MessageDescriptor]struct{}, enums
map[protoreflect.EnumDescriptor]struct{}) {
if md == nil {
return
}
@@ -83,18 +97,22 @@ func collectMessage(md protoreflect.MessageDescriptor,
messages map[protoreflect
fields := md.Fields()
for i := 0; i < fields.Len(); i++ {
- collectField(fields.Get(i), messages)
+ collectField(fields.Get(i), messages, enums)
}
nestedMessages := md.Messages()
for i := 0; i < nestedMessages.Len(); i++ {
- collectMessage(nestedMessages.Get(i), messages)
+ collectMessage(nestedMessages.Get(i), messages, enums)
}
}
-func collectField(fd protoreflect.FieldDescriptor, messages
map[protoreflect.MessageDescriptor]struct{}) {
+func collectField(fd protoreflect.FieldDescriptor, messages
map[protoreflect.MessageDescriptor]struct{}, enums
map[protoreflect.EnumDescriptor]struct{}) {
if fd == nil {
return
}
- collectMessage(fd.Message(), messages)
+ if fd.Kind() == protoreflect.EnumKind {
+ enums[fd.Enum()] = struct{}{}
+ return
+ }
+ collectMessage(fd.Message(), messages, enums)
}
diff --git a/tools/protoc-gen-triple-openapi/internal/converter/schema/util.go
b/tools/protoc-gen-triple-openapi/internal/converter/schema/util.go
index 21605d7b0..f51719762 100644
--- a/tools/protoc-gen-triple-openapi/internal/converter/schema/util.go
+++ b/tools/protoc-gen-triple-openapi/internal/converter/schema/util.go
@@ -55,11 +55,16 @@ func messageToSchema(tt protoreflect.MessageDescriptor)
(string, *base.Schema) {
func fieldToSchema(parent *base.SchemaProxy, tt protoreflect.FieldDescriptor)
*base.SchemaProxy {
if tt.IsMap() {
- // Handle maps
root := ScalarFieldToSchema(parent, tt, false)
root.Title = string(tt.Name())
root.Type = []string{"object"}
- // TODO: todo
+ value := tt.MapValue()
+ switch value.Kind() {
+ case protoreflect.MessageKind, protoreflect.EnumKind:
+ root.AdditionalProperties =
&base.DynamicValue[*base.SchemaProxy, bool]{A: ReferenceFieldToSchema(parent,
value)}
+ default:
+ root.AdditionalProperties =
&base.DynamicValue[*base.SchemaProxy, bool]{A:
base.CreateSchemaProxy(ScalarFieldToSchema(parent, value, true))}
+ }
root.Description = ""
return base.CreateSchemaProxy(root)
} else if tt.IsList() {
@@ -137,6 +142,20 @@ func ScalarFieldToSchema(parent *base.SchemaProxy, tt
protoreflect.FieldDescript
return s
}
+func enumToSchema(tt protoreflect.EnumDescriptor) (string, *base.Schema) {
+ values := tt.Values()
+ enum := make([]*yaml.Node, 0, values.Len())
+ for i := 0; i < values.Len(); i++ {
+ enum = append(enum,
CreateStringNode(string(values.Get(i).Name())))
+ }
+
+ return string(tt.FullName()), &base.Schema{
+ Title: string(tt.Name()),
+ Type: []string{"string"},
+ Enum: enum,
+ }
+}
+
func ReferenceFieldToSchema(parent *base.SchemaProxy, tt
protoreflect.FieldDescriptor) *base.SchemaProxy {
switch tt.Kind() {
case protoreflect.MessageKind: