Skip to content

Commit

Permalink
Draft: Fix names with special characters and numbers on the beggining (
Browse files Browse the repository at this point in the history
…#80)

* - Update gnostic dependency to latest version
- Add '_' at the beggining of enum fields that start with a number

* Replace hyphens with underscore

* Add test cases

* Handle messages with a leading number

* Escape the + char

* Remove functionality that changes output name

* Fix test

---------

Co-authored-by: Lorenz Hofmann-Wellenhof <lorenzhofmann.w@gmail.com>
  • Loading branch information
ChepChaf and LorenzHW authored Jun 19, 2023
1 parent 4ca5047 commit c8bc7e1
Show file tree
Hide file tree
Showing 10 changed files with 84 additions and 37 deletions.
1 change: 1 addition & 0 deletions generator/checker_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ func TestNewFeatureCheckerParameters(t *testing.T) {
checker := NewGrpcChecker(documentv3)
messages := checker.Run()
expectedMessageKeys := [][]string{
{"components", "parameters", "required"},
{"paths", "/testParameterQueryEnum", "get", "parameters", "explode"},
{"paths", "/testParameterQueryEnum", "get", "parameters", "schema", "items", "default"},
{"paths", "/testParameterPathEnum/{param1}", "get", "parameters", "schema", "default"},
Expand Down
17 changes: 14 additions & 3 deletions generator/generator_messages.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@ func buildAllMessageDescriptors(renderer *Renderer) (messageDescriptors []*dpb.D
}
if isRequestParameter(surfaceType) {
validateRequestParameter(surfaceField)
// convert base message to parameter message, e.g., GetPetRequest -> GetPetParameters
message.Name = &surfaceType.Name
}

addFieldDescriptor(message, surfaceField, i, renderer.Package)
Expand Down Expand Up @@ -250,12 +248,25 @@ func addEnumDescriptorIfNecessary(message *dpb.DescriptorProto, f *surface_v1.Fi
}
}

func getEnumFieldName(value string) string {
name := strings.ToUpper(value)
name = strings.ReplaceAll(name, "-", "_")

firstChar := name[0]

if '0' <= firstChar && firstChar <= '9' {
return "_" + name
}

return name
}

// buildEnumDescriptorProto builds the necessary descriptor to render a enum. (https://developers.google.com/protocol-buffers/docs/proto3#enum)
func buildEnumDescriptorProto(f *surface_v1.Field) *dpb.EnumDescriptorProto {
enumDescriptor := &dpb.EnumDescriptorProto{Name: &f.NativeType}
for enumCtr, value := range f.EnumValues {
num := int32(enumCtr)
name := strings.ToUpper(value)
name := getEnumFieldName(value)
valueDescriptor := &dpb.EnumValueDescriptorProto{
Name: &name,
Number: &num,
Expand Down
10 changes: 2 additions & 8 deletions generator/generator_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ func buildMethodDescriptor(method *surface_v1.Method, types []*surface_v1.Type)
if err != nil {
return nil, err
}
inputType, outputType := buildInputTypeAndOutputType(method.ParametersTypeName, method.ResponsesTypeName, types)
inputType, outputType := buildInputTypeAndOutputType(method.ParametersTypeName, method.ResponsesTypeName)
methodDescriptor = &dpb.MethodDescriptorProto{
Name: &method.HandlerName,
InputType: &inputType,
Expand Down Expand Up @@ -120,7 +120,7 @@ func getRequestBodyForRequestParameter(name string, types []*surface_v1.Type) st
return ""
}

func buildInputTypeAndOutputType(parametersTypeName, responseTypeName string, types []*surface_v1.Type) (inputType, outputType string) {
func buildInputTypeAndOutputType(parametersTypeName, responseTypeName string) (inputType, outputType string) {
inputType = parametersTypeName
outputType = responseTypeName
if parametersTypeName == "" {
Expand All @@ -129,12 +129,6 @@ func buildInputTypeAndOutputType(parametersTypeName, responseTypeName string, ty
if responseTypeName == "" {
outputType = "google.protobuf.Empty"
}
for _, t := range types {
// convert base input type to parameter input type, e.g., GetPetRequest -> GetPetParameters
if t.TypeName == inputType && t.Name != inputType {
inputType = t.Name
}
}
return inputType, outputType
}

Expand Down
22 changes: 19 additions & 3 deletions generator/language.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
Expand Down Expand Up @@ -283,7 +283,7 @@ func protoTypeName(originalName string) (name string) {
return name
}

// Removes characters which are not allowed for message names or field names inside .proto files.
// CleanName removes characters which are not allowed for message names or field names inside .proto files.
func CleanName(name string) string {
name = strings.Replace(name, "application/json", "", -1)
name = strings.Replace(name, ".", "_", -1)
Expand All @@ -295,7 +295,23 @@ func CleanName(name string) string {
name = strings.Replace(name, "}", "", -1)
name = strings.Replace(name, "/", "_", -1)
name = strings.Replace(name, "$", "", -1)
return name
name = strings.Replace(name, "+", "", -1)
return escapeNumericFirstChar(name)
}

// escapeNumericFirstChar add _ to the beggining of the string if first char is a number
func escapeNumericFirstChar(str string) string {
if len(str) == 0 {
return str
}

firstChar := str[0]

if '0' <= firstChar && firstChar <= '9' {
return "_" + str
}

return str
}

// toCamelCase converts str to CamelCase
Expand Down
4 changes: 2 additions & 2 deletions generator/testfiles/goldstandard/other.proto
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ message TestAnyOfApiResponse {
}

//TestExernalReference2Parameters holds parameters to TestExernalReference2
message TestExernalReference2Parameters {
message TestExernalReference2Request {
parameters.Parameter2 parameter2 = 1;
}

Expand Down Expand Up @@ -137,7 +137,7 @@ service Other {
option (google.api.http) = { get:"/testExternalReference" };
}

rpc TestExernalReference2 ( TestExernalReference2Parameters ) returns ( google.protobuf.Empty ) {
rpc TestExernalReference2 ( TestExernalReference2Request ) returns ( google.protobuf.Empty ) {
option (google.api.http) = { get:"/testExternalReference2" body:"parameter2" };
}

Expand Down
37 changes: 25 additions & 12 deletions generator/testfiles/goldstandard/parameters.proto
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ message Parameter2 {
}

//TestParameterQueryParameters holds parameters to TestParameterQuery
message TestParameterQueryParameters {
message TestParameterQueryRequest {
int32 param1 = 1;
}

//TestParameterQueryEnumParameters holds parameters to TestParameterQueryEnum
message TestParameterQueryEnumParameters {
message TestParameterQueryEnumRequest {
repeated Param2 param2 = 1;

enum Param2 {
Expand All @@ -33,16 +33,20 @@ message TestParameterQueryEnumParameters {
HUSKY = 1;

RETRIEVER = 2;

_5CHIHUAHUA = 3;

SHARPEI_2 = 4;
}
}

//TestParameterPathParameters holds parameters to TestParameterPath
message TestParameterPathParameters {
message TestParameterPathRequest {
string param3 = 1;
}

//TestParameterPathEnumParameters holds parameters to TestParameterPathEnum
message TestParameterPathEnumParameters {
message TestParameterPathEnumRequest {
Param4 param4 = 1;

enum Param4 {
Expand All @@ -53,40 +57,49 @@ message TestParameterPathEnumParameters {
}

//TestParameterMultiplePathParameters holds parameters to TestParameterMultiplePath
message TestParameterMultiplePathParameters {
message TestParameterMultiplePathRequest {
string param5 = 1;

string param6 = 2;
}

//TestParameterReferenceParameters holds parameters to TestParameterReference
message TestParameterReferenceParameters {
message TestParameterReferenceRequest {
Parameter1 parameter1 = 1;
}

//5testRouteWithNumberParameters holds parameters to 5testRouteWithNumber
message _5testRouteWithNumberRequest {
Parameter1 parameter1 = 1;
}

service Parameters {
rpc TestParameterQuery ( TestParameterQueryParameters ) returns ( google.protobuf.Empty ) {
rpc TestParameterQuery ( TestParameterQueryRequest ) returns ( google.protobuf.Empty ) {
option (google.api.http) = { get:"/testParameterQuery" };
}

rpc TestParameterQueryEnum ( TestParameterQueryEnumParameters ) returns ( google.protobuf.Empty ) {
rpc TestParameterQueryEnum ( TestParameterQueryEnumRequest ) returns ( google.protobuf.Empty ) {
option (google.api.http) = { get:"/testParameterQueryEnum" };
}

rpc TestParameterPath ( TestParameterPathParameters ) returns ( google.protobuf.Empty ) {
rpc TestParameterPath ( TestParameterPathRequest ) returns ( google.protobuf.Empty ) {
option (google.api.http) = { get:"/testParameterPath/{param1}" };
}

rpc TestParameterPathEnum ( TestParameterPathEnumParameters ) returns ( google.protobuf.Empty ) {
rpc TestParameterPathEnum ( TestParameterPathEnumRequest ) returns ( google.protobuf.Empty ) {
option (google.api.http) = { get:"/testParameterPathEnum/{param1}" };
}

rpc TestParameterMultiplePath ( TestParameterMultiplePathParameters ) returns ( google.protobuf.Empty ) {
rpc TestParameterMultiplePath ( TestParameterMultiplePathRequest ) returns ( google.protobuf.Empty ) {
option (google.api.http) = { get:"/testParameterMultiplePath/{param1}/{param2}" };
}

rpc TestParameterReference ( TestParameterReferenceParameters ) returns ( google.protobuf.Empty ) {
rpc TestParameterReference ( TestParameterReferenceRequest ) returns ( google.protobuf.Empty ) {
option (google.api.http) = { get:"/testParameterReference" };
}

rpc _5testRouteWithNumber ( _5testRouteWithNumberRequest ) returns ( google.protobuf.Empty ) {
option (google.api.http) = { get:"/5testRouteWithNumber" };
}
}

8 changes: 4 additions & 4 deletions generator/testfiles/goldstandard/requestbodies.proto
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,21 @@ message Person {
}

//TestRequestBodyParameters holds parameters to TestRequestBody
message TestRequestBodyParameters {
message TestRequestBodyRequest {
Person person = 1;
}

//TestRequestBodyReferenceParameters holds parameters to TestRequestBodyReference
message TestRequestBodyReferenceParameters {
message TestRequestBodyReferenceRequest {
Person person = 1;
}

service Requestbodies {
rpc TestRequestBody ( TestRequestBodyParameters ) returns ( google.protobuf.Empty ) {
rpc TestRequestBody ( TestRequestBodyRequest ) returns ( google.protobuf.Empty ) {
option (google.api.http) = { get:"/testRequestBody" body:"person" };
}

rpc TestRequestBodyReference ( TestRequestBodyReferenceParameters ) returns ( google.protobuf.Empty ) {
rpc TestRequestBodyReference ( TestRequestBodyReferenceRequest ) returns ( google.protobuf.Empty ) {
option (google.api.http) = { get:"/testRequestBodyReference" body:"person" };
}
}
Expand Down
16 changes: 14 additions & 2 deletions generator/testfiles/parameters.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ paths:
responses:
200:
description: success
/testParameterQueryEnum: #TODO: Generates invalid proto for integer enums
/testParameterQueryEnum:
get:
operationId: testParameterQueryEnum
parameters:
Expand All @@ -40,6 +40,8 @@ paths:
- Dingo
- Husky
- Retriever
- 5Chihuahua
- Sharpei-2
default: Husky
responses:
200:
Expand Down Expand Up @@ -95,6 +97,14 @@ paths:
responses:
200:
description: success
/5testRouteWithNumber:
get:
operationId: 5testRouteWithNumber
parameters:
- $ref: '#/components/parameters/Parameter1'
responses:
200:
description: successful operation
components:
parameters:
Parameter1:
Expand All @@ -103,9 +113,11 @@ components:
schema:
type: integer
format: int64
required: false
Parameter2:
name: param8
in: path
schema:
type: integer
format: int64
format: int64
required: true
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ go 1.20
require (
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b
github.com/golang/protobuf v1.5.2
github.com/google/gnostic v0.6.8
github.com/google/gnostic v0.6.9
github.com/google/go-cmp v0.5.6
github.com/grpc-ecosystem/grpc-gateway v1.16.0
github.com/jhump/protoreflect v1.10.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/google/gnostic v0.6.8 h1:bT56GPYBWh1tvBuBEd94qcS3+60b+y0HQur0ITkGuCk=
github.com/google/gnostic v0.6.8/go.mod h1:Nm8234We1lq6iB9OmlgNv3nH91XLLVZHCDayfA3xq+E=
github.com/google/gnostic v0.6.9 h1:ZK/5VhkoX835RikCHpSUJV9a+S3e1zLh59YnyWeBW+0=
github.com/google/gnostic v0.6.9/go.mod h1:Nm8234We1lq6iB9OmlgNv3nH91XLLVZHCDayfA3xq+E=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
Expand Down

0 comments on commit c8bc7e1

Please sign in to comment.