forked from google/gnostic-go-generator
-
Notifications
You must be signed in to change notification settings - Fork 0
/
language.go
123 lines (111 loc) · 3.15 KB
/
language.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
// Copyright 2019 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// 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
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package main
import (
"strings"
"unicode"
gnosticGrpc "github.com/googleapis/gnostic-grpc/generator"
surface "github.com/googleapis/gnostic/surface"
)
type GoLanguageModel struct{}
func NewGoLanguageModel() *GoLanguageModel {
return &GoLanguageModel{}
}
// Prepare sets language-specific properties for all types and methods.
func (language *GoLanguageModel) Prepare(model *surface.Model, inputDocumentType string) {
for _, t := range model.Types {
// determine the type used for Go language implementation of the type
t.TypeName = strings.Title(filteredTypeName(t.Name))
for _, f := range t.Fields {
f.FieldName = goFieldName(f.Name, f.Type)
f.ParameterName = goParameterName(f.Name, f.Type)
switch f.Type {
case "boolean":
f.NativeType = "bool"
case "number":
f.NativeType = "int"
case "integer":
switch f.Format {
case "int32":
f.NativeType = "int32"
case "int64":
f.NativeType = "int64"
default:
f.NativeType = "int64"
}
case "object":
f.NativeType = "interface{}"
case "string":
f.NativeType = "string"
default:
f.NativeType = strings.Title(filteredTypeName(f.Type))
}
}
}
for _, m := range model.Methods {
m.HandlerName = "Handle" + m.Name
m.ProcessorName = m.Name
m.ClientName = m.Name
m.ResponsesTypeName = strings.Title(filteredTypeName(m.ResponsesTypeName))
}
gnosticGrpc.AdjustSurfaceModel(model, inputDocumentType)
}
func goParameterName(originalName string, t string) string {
name := gnosticGrpc.CleanName(originalName)
if name == "" {
name = gnosticGrpc.CleanName(t)
}
// lowercase first letter
a := []rune(name)
a[0] = unicode.ToLower(a[0])
name = string(a)
// avoid reserved words
if name == "type" {
return "myType"
}
return name
}
func goFieldName(name string, t string) string {
name = gnosticGrpc.CleanName(name)
if name == "" {
name = gnosticGrpc.CleanName(t)
}
return snakeToUpperCamel(name)
}
func snakeToUpperCamel(snakeCase string) (camelCase string) {
isToUpper := false
for _, runeValue := range snakeCase {
if isToUpper {
camelCase += strings.ToUpper(string(runeValue))
isToUpper = false
} else {
if runeValue == '_' {
isToUpper = true
} else {
camelCase += string(runeValue)
}
}
}
camelCase = strings.Title(camelCase)
return
}
func filteredTypeName(typeName string) (name string) {
// first take the last path segment
parts := strings.Split(typeName, "/")
name = parts[len(parts)-1]
// then take the last part of a dotted name
parts = strings.Split(name, ".")
name = parts[len(parts)-1]
return name
}