Skip to content

Commit

Permalink
Merge pull request #33 from eclipse/fix/camelCaseClassNames
Browse files Browse the repository at this point in the history
feat: [open-models] short names
  • Loading branch information
veith authored Nov 12, 2024
2 parents afe4645 + b7b337c commit c28eb5a
Show file tree
Hide file tree
Showing 9 changed files with 107 additions and 63 deletions.
13 changes: 8 additions & 5 deletions protoc-gen-open-models/pkg/generator/Imports.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,17 @@ import (

type ImportMap struct {
// map[__modulepath__]map[__import__]bool
Imports map[string]map[string]bool
Imports map[string]map[string]string
// ^ ^ ^
// | | |
// modulepath class fullqualified class
}

func (im ImportMap) AddImport(typescriptModulePath string, cls string) {
func (im ImportMap) AddImport(typescriptModulePath string, className string, fullQualifiedClassName string) {
if im.Imports[typescriptModulePath] == nil {
im.Imports[typescriptModulePath] = map[string]bool{}
im.Imports[typescriptModulePath] = map[string]string{}
}
im.Imports[typescriptModulePath][cls] = true
im.Imports[typescriptModulePath][className] = fullQualifiedClassName
}

func (im ImportMap) Render() string {
Expand All @@ -33,6 +36,6 @@ func (im ImportMap) Render() string {

var ImportTemplate = `
{{- range $import, $clsMap := .Imports}}
{{ $first := true }}import { {{range $cls, $_ := $clsMap}}{{if not $first}}, {{else}}{{$first = false}}{{end}}{{$cls}}{{end}} } from "{{$import}}";
{{ $first := true }}import { {{range $cls, $as := $clsMap}}{{if not $first}}, {{else}}{{$first = false}}{{end}}{{$cls}}{{if $as}} as {{$as}}{{end}}{{end}} } from "{{$import}}";
{{end}}
`
10 changes: 9 additions & 1 deletion protoc-gen-open-models/pkg/generator/LiteralType.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func (r *LiteralType) Render() string {

func prepareLiteralType(message *sourceinfo.MessageInfo, imports ImportMap) LiteralType {
literalType := LiteralType{
Name: fullQualifiedName(message.Package, fullQualifiedName(message.Name, "")),
Name: PrefixReservedWords(strcase.ToCamel(message.Name)),
Fields: nil,
LeadingComments: multilineComment(message.Info.GetLeadingComments()),
}
Expand All @@ -76,3 +76,11 @@ func fullQualifiedName(pkg string, name string) string {

return strcase.ToCamel(strings.Join(p, "")) + name
}

func dotToCamel(name string) string {
p := []string{}
for _, s := range strings.Split(name, ".") {
p = append(p, strings.ToUpper(s[:1])+s[1:])
}
return strcase.ToCamel(strings.Join(p, ""))
}
3 changes: 2 additions & 1 deletion protoc-gen-open-models/pkg/generator/ModelType.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/bufbuild/protoplugin"
"github.com/eclipse/eclipsefuro/protoc-gen-open-models/pkg/sourceinfo"
openapi_v3 "github.com/google/gnostic/openapiv3"
"github.com/iancoleman/strcase"
"slices"
"strings"
"text/template"
Expand Down Expand Up @@ -178,7 +179,7 @@ func prepareModelType(message *sourceinfo.MessageInfo, imports ImportMap, si sou
readonlyFields := []string{}

modelType := ModelType{
Name: fullQualifiedName(message.Package, fullQualifiedName(message.Name, "")),
Name: PrefixReservedWords(strcase.ToCamel(message.Name)),
Fields: nil,
LeadingComments: multilineComment(message.Info.GetLeadingComments()),
MetaTypeName: message.Package + "." + message.Name,
Expand Down
16 changes: 9 additions & 7 deletions protoc-gen-open-models/pkg/generator/ServiceType.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bytes"
"errors"
"github.com/eclipse/eclipsefuro/protoc-gen-open-models/pkg/sourceinfo"
"github.com/iancoleman/strcase"
"google.golang.org/genproto/googleapis/api/annotations"
"path/filepath"
"strings"
Expand Down Expand Up @@ -63,17 +64,17 @@ func (r *ServiceType) Render() string {

func prepareServiceType(service sourceinfo.ServiceInfo, imports ImportMap) ServiceType {

imports.AddImport("@furo/open-models/dist/Fetcher", "Fetcher")
imports.AddImport("@furo/open-models/dist/Fetcher", "Fetcher", "")

pathSegments := strings.Split(service.Package, ".")
for i, _ := range pathSegments {
pathSegments[i] = ".."
}

imports.AddImport(strings.Join(pathSegments, "/")+"/API_OPTIONS", "API_OPTIONS")
imports.AddImport(strings.Join(pathSegments, "/")+"/API_OPTIONS", "API_OPTIONS", "")

serviceType := ServiceType{
Name: fullQualifiedName(service.Package, service.Name),
Name: strcase.ToCamel(service.Name),
Methods: make([]ServiceMethods, 0, len(service.Methods)),
LeadingComments: multilineComment(service.Info.GetLeadingComments()),
Package: service.Package,
Expand All @@ -83,7 +84,8 @@ func prepareServiceType(service sourceinfo.ServiceInfo, imports ImportMap) Servi

requestTypeFQ := fullQualifiedTypeName(method.Method.GetInputType())
responseTypeFQ := fullQualifiedTypeName(method.Method.GetOutputType())

classNameOut := allTypes[method.Method.GetOutputType()].Name
classNameIn := allTypes[method.Method.GetInputType()].Name
fieldPackage := strings.Split("."+service.Package, ".")

relIn, _ := filepath.Rel(strings.Join(fieldPackage, "/"), "/"+typenameToPath(method.Method.GetInputType()))
Expand All @@ -94,14 +96,14 @@ func prepareServiceType(service sourceinfo.ServiceInfo, imports ImportMap) Servi
if !strings.HasPrefix(relOut, "..") {
relOut = "./" + relOut
}
imports.AddImport(relIn, "I"+requestTypeFQ)
imports.AddImport(relOut, "I"+responseTypeFQ)
imports.AddImport(relIn, "I"+PrefixReservedWords(classNameIn), "I"+requestTypeFQ)
imports.AddImport(relOut, "I"+PrefixReservedWords(classNameOut), "I"+responseTypeFQ)

verb, path, err := extractPathAndPattern(method.HttpRule.ApiOptions)
// on err, we have no REST endpoints
if err == nil {
serviceMethods := ServiceMethods{
Name: method.Name,
Name: PrefixReservedWords(method.Name),
RequestTypeLiteral: "I" + requestTypeFQ,
ResponseTypeLiteral: "I" + responseTypeFQ,
Verb: verb,
Expand Down
3 changes: 2 additions & 1 deletion protoc-gen-open-models/pkg/generator/TransportType.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package generator
import (
"bytes"
"github.com/eclipse/eclipsefuro/protoc-gen-open-models/pkg/sourceinfo"
"github.com/iancoleman/strcase"
"text/template"
)

Expand Down Expand Up @@ -50,7 +51,7 @@ export interface T{{.Name}} {

func prepareTransportType(message *sourceinfo.MessageInfo, imports ImportMap) TransportType {
transportType := TransportType{
Name: fullQualifiedName(message.Package, fullQualifiedName(message.Name, "")),
Name: PrefixReservedWords(strcase.ToCamel(message.Name)),
Fields: nil,
LeadingComments: multilineComment(message.Info.GetLeadingComments()),
}
Expand Down
10 changes: 5 additions & 5 deletions protoc-gen-open-models/pkg/generator/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ func createEnum(si sourceinfo.SourceInfo, enum *sourceinfo.EnumInfo) string {
options = append(options, o)
}

content := "export enum " + fullQualifiedName(enum.Package, fullQualifiedName(enum.Name, "")) + " {\n" + strings.Join(options, "\n") + "\n}"
content := "export enum " + dotToCamel(PrefixReservedWords(enum.Name)) + " {\n" + strings.Join(options, "\n") + "\n}"
parts := []string{
"// Code generated by furo protoc-gen-open-models. DO NOT EDIT.",
"// protoc-gen-open-models version: ????",
Expand All @@ -149,9 +149,9 @@ func createEnum(si sourceinfo.SourceInfo, enum *sourceinfo.EnumInfo) string {

func createOpenModel(si sourceinfo.SourceInfo, message *sourceinfo.MessageInfo, request protoplugin.Request) string {

imports := ImportMap{Imports: make(map[string]map[string]bool)}
imports.AddImport("@furo/open-models/dist/index", "FieldNode")
imports.AddImport("@furo/open-models/dist/index", "Registry")
imports := ImportMap{Imports: make(map[string]map[string]string)}
imports.AddImport("@furo/open-models/dist/index", "FieldNode", "")
imports.AddImport("@furo/open-models/dist/index", "Registry", "")

literalType := prepareLiteralType(message, imports)
transportType := prepareTransportType(message, imports)
Expand All @@ -170,7 +170,7 @@ func createOpenModel(si sourceinfo.SourceInfo, message *sourceinfo.MessageInfo,
}

func createOpenModelService(si sourceinfo.SourceInfo, service sourceinfo.ServiceInfo) string {
imports := ImportMap{Imports: make(map[string]map[string]bool)}
imports := ImportMap{Imports: make(map[string]map[string]string)}
serviveType := prepareServiceType(service, imports)
parts := []string{
"// Code generated by furo protoc-gen-open-models. DO NOT EDIT.",
Expand Down
76 changes: 44 additions & 32 deletions protoc-gen-open-models/pkg/generator/modelTypeResolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,16 +50,16 @@ func resolveModelType(imports ImportMap, field sourceinfo.FieldInfo) (
if t, ok := ModelTypesMap[fieldType]; ok {
primitiveType := PrimitivesMap[fieldType]
if field.Field.Label.String() == "LABEL_REPEATED" {
imports.AddImport("@furo/open-models/dist/index", "ARRAY")
imports.AddImport("@furo/open-models/dist/index", ModelTypesMap[fieldType])
imports.AddImport("@furo/open-models/dist/index", "ARRAY", "")
imports.AddImport("@furo/open-models/dist/index", ModelTypesMap[fieldType], "")
return "ARRAY<" + t + ", " + primitiveType + ">",
"__TypeSetter",
primitiveType + "[]",
"ARRAY<" + t + ", " + primitiveType + ">",
"", // ARRAY is uses a typesetter
t
}
imports.AddImport("@furo/open-models/dist/index", ModelTypesMap[fieldType])
imports.AddImport("@furo/open-models/dist/index", ModelTypesMap[fieldType], "")
return t, "__PrimitivesSetter", primitiveType, t, "", t
}

Expand All @@ -80,6 +80,7 @@ func resolveModelType(imports ImportMap, field sourceinfo.FieldInfo) (
if *nested.Field[1].Type == descriptorpb.FieldDescriptorProto_TYPE_MESSAGE {
// message
m := *nested.Field[1].TypeName
className := allTypes[m].Name
maptype = m[1:len(m)]
// WELL KNOWN

Expand All @@ -89,15 +90,15 @@ func resolveModelType(imports ImportMap, field sourceinfo.FieldInfo) (

// ANY
if typeName == "Any" {
imports.AddImport("@furo/open-models/dist/index", "type IAny")
imports.AddImport("@furo/open-models/dist/index", "ANY")
imports.AddImport("@furo/open-models/dist/index", "type IAny", "")
imports.AddImport("@furo/open-models/dist/index", "ANY", "")
return "ANY", "__TypeSetter", "IAny", "ANY", "", "ANY"
}
primitiveMapType := WellKnownTypesMap[typeName]

// for model types return "MAP<string, STRING, string>;"
imports.AddImport("@furo/open-models/dist/index", "MAP")
imports.AddImport("@furo/open-models/dist/index", ModelTypesMap[primitiveMapType])
imports.AddImport("@furo/open-models/dist/index", "MAP", "")
imports.AddImport("@furo/open-models/dist/index", ModelTypesMap[primitiveMapType], "")
return "MAP<string," + ModelTypesMap[primitiveMapType] + "," + PrimitivesMap[primitiveMapType] + ">",
"__TypeSetter",
"{ [key: string]: " + PrimitivesMap[primitiveMapType] + " }",
Expand All @@ -111,8 +112,8 @@ func resolveModelType(imports ImportMap, field sourceinfo.FieldInfo) (
if !strings.HasPrefix(rel, "..") {
rel = "./" + rel
}
imports.AddImport(rel, fullQualifiedName(maptype, ""))
imports.AddImport("@furo/open-models/dist/index", "MAP")
imports.AddImport(rel, PrefixReservedWords(className), fullQualifiedName(maptype, ""))
imports.AddImport("@furo/open-models/dist/index", "MAP", "")

return "MAP<string," + fullQualifiedName(maptype, "") + "," + fullQualifiedName(maptype, "") + ">",
"__TypeSetter",
Expand All @@ -123,8 +124,8 @@ func resolveModelType(imports ImportMap, field sourceinfo.FieldInfo) (
}
}
// for model types return "MAP<string, STRING, string>;"
imports.AddImport("@furo/open-models/dist/index", "MAP")
imports.AddImport("@furo/open-models/dist/index", ModelTypesMap[maptype])
imports.AddImport("@furo/open-models/dist/index", "MAP", "")
imports.AddImport("@furo/open-models/dist/index", ModelTypesMap[maptype], "")
return "MAP<string," + ModelTypesMap[maptype] + "," + PrimitivesMap[maptype] + ">",
"__TypeSetter",
"{ [key: string]: " + PrimitivesMap[maptype] + " }",
Expand All @@ -146,17 +147,18 @@ func resolveModelType(imports ImportMap, field sourceinfo.FieldInfo) (

// ANY
if typeName == "Any" {
imports.AddImport("@furo/open-models/dist/index", "type IAny")
imports.AddImport("@furo/open-models/dist/index", "ANY")
imports.AddImport("@furo/open-models/dist/index", "type IAny", "")
imports.AddImport("@furo/open-models/dist/index", "ANY", "")
return "ANY", "__TypeSetter", "IAny", "ANY", "", "ANY"
}
primitiveType := WellKnownTypesMap[typeName]
imports.AddImport("@furo/open-models/dist/index", typeName)
imports.AddImport("@furo/open-models/dist/index", typeName, "")
return typeName, "__TypeSetter", primitiveType + "| null", typeName, "", typeName
}

// MESSAGE
t := field.Field.GetTypeName()
className := dotToCamel(allTypes[t].Name)
if strings.HasPrefix(t, ".") {
t = t[1:]
}
Expand All @@ -168,12 +170,21 @@ func resolveModelType(imports ImportMap, field sourceinfo.FieldInfo) (
// do not add import for the same file (direct recursion types)
t = fullQualifiedName(t, "")
if field.Message.GetName() != importFile {
imports.AddImport("./"+importFile, t)
imports.AddImport("./"+importFile, PrefixReservedWords(className), t)
}

if field.Field.Label.String() == "LABEL_REPEATED" {
imports.AddImport("@furo/open-models/dist/index", "ARRAY")
imports.AddImport("@furo/open-models/dist/index", "ARRAY", "")

// if we are in the same package, we use the classNames
if field.Field.GetTypeName() == "."+field.Package+"."+field.Message.GetName() {
return "ARRAY<" + className + ", I" + className + ">",
"__TypeSetter",
"I" + className + "[]",
"ARRAY<" + className + ", I" + className + ">",
"",
className
}
return "ARRAY<" + t + ", I" + t + ">",
"__TypeSetter",
"I" + t + "[]",
Expand All @@ -183,23 +194,23 @@ func resolveModelType(imports ImportMap, field sourceinfo.FieldInfo) (
}
// if a field type equals the package name + message type we have a direct recusrion
if field.Field.GetTypeName() == "."+field.Package+"."+field.Message.GetName() {
imports.AddImport("@furo/open-models/dist/index", "RECURSION")
return "RECURSION<" + t + ", I" + t + ">",
imports.AddImport("@furo/open-models/dist/index", "RECURSION", "")
return "RECURSION<" + className + ", I" + className + ">",
"__TypeSetter",
"I" + t,
"RECURSION<" + t + ", I" + t + ">",
"I" + className,
"RECURSION<" + className + ", I" + className + ">",
"",
t
className
}
// todo: check for deep recursion
if deepRecursionCheck(field.Field.GetTypeName()) {
imports.AddImport("@furo/open-models/dist/index", "RECURSION")
return "RECURSION<" + t + ", I" + t + ">",
imports.AddImport("@furo/open-models/dist/index", "RECURSION", "")
return "RECURSION<" + className + ", I" + className + ">",
"__TypeSetter",
"I" + t,
"RECURSION<" + t + ", I" + t + ">",
"I" + className,
"RECURSION<" + className + ", I" + className + ">",
"",
t
className
}

return t, "__TypeSetter", "I" + t, t, "", t
Expand All @@ -220,10 +231,10 @@ func resolveModelType(imports ImportMap, field sourceinfo.FieldInfo) (
// do not add import for the same file (direct recursion types)
t = fullQualifiedName(t, "")
if field.Message.GetName() != importFile {
imports.AddImport(rel, t)
imports.AddImport(rel, PrefixReservedWords(className), t)
}
if field.Field.Label.String() == "LABEL_REPEATED" {
imports.AddImport("@furo/open-models/dist/index", "ARRAY")
imports.AddImport("@furo/open-models/dist/index", "ARRAY", "")

return "ARRAY<" + t + ", I" + t + ">",
"__TypeSetter",
Expand All @@ -239,6 +250,7 @@ func resolveModelType(imports ImportMap, field sourceinfo.FieldInfo) (
}
if fieldType == "TYPE_ENUM" {
t := field.Field.GetTypeName()
className := dotToCamel(allEnums[t].Name)
if strings.HasPrefix(t, ".") {
t = t[1:]
}
Expand All @@ -248,8 +260,8 @@ func resolveModelType(imports ImportMap, field sourceinfo.FieldInfo) (
importFile := t[len(field.Package)+1:]
fqn := fullQualifiedName(t, "")

imports.AddImport("@furo/open-models/dist/index", "ENUM")
imports.AddImport("./"+importFile, fqn)
imports.AddImport("@furo/open-models/dist/index", "ENUM", "")
imports.AddImport("./"+importFile, PrefixReservedWords(className), fqn)
// create correct importFile for nested types

return "ENUM<" + fqn + ">", "__TypeSetter", fqn, "ENUM<" + fqn + ">", "", "ENUM<" + fqn + ">"
Expand All @@ -264,8 +276,8 @@ func resolveModelType(imports ImportMap, field sourceinfo.FieldInfo) (
fqn := fullQualifiedName(t, "")

// enum are without prefix
imports.AddImport("@furo/open-models/dist/index", "ENUM")
imports.AddImport(rel, fqn)
imports.AddImport("@furo/open-models/dist/index", "ENUM", "")
imports.AddImport(rel, PrefixReservedWords(className), fqn)
if field.Field.Label.String() == "LABEL_REPEATED" {
return "ENUM<" + fqn + ">", "__TypeSetter", fqn, "ENUM<" + fqn + ">", "", "ENUM<" + fqn + ">"
}
Expand Down
13 changes: 13 additions & 0 deletions protoc-gen-open-models/pkg/generator/reservedWords.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package generator

var ReservedWords = map[string]struct{}{
"Object": {},
"Any": {},
}

func PrefixReservedWords(className string) string {
if _, ok := ReservedWords[className]; ok {
return "X" + className
}
return className
}
Loading

0 comments on commit c28eb5a

Please sign in to comment.