github.com/sacloud/iaas-api-go@v1.12.0/internal/dsl/model.go (about) 1 // Copyright 2022-2023 The sacloud/iaas-api-go Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package dsl 16 17 import ( 18 "fmt" 19 20 "github.com/sacloud/iaas-api-go/internal/dsl/meta" 21 ) 22 23 // Models APIのリクエスト/レスポンスなどのデータ型を示すモデル 24 type Models []*Model 25 26 // ImportStatements コード生成時に利用するimport文を生成する 27 func (m Models) ImportStatements(additionalImports ...string) []string { 28 ss := wrapByDoubleQuote(additionalImports...) 29 for _, model := range m { 30 ss = append(ss, model.ImportStatements()...) 31 } 32 return uniqStrings(ss) 33 } 34 35 // IsEmpty 空であるか判定 36 func (m Models) IsEmpty() bool { 37 return len(m) == 0 38 } 39 40 // UniqByName NameでユニークなModelの一覧を返す 41 func (m Models) UniqByName() Models { 42 models := Models{} 43 isUniq := func(name string) bool { 44 for _, model := range models { 45 if model.Name == name { 46 return false 47 } 48 } 49 return true 50 } 51 for _, model := range m { 52 if isUniq(model.Name) { 53 models = append(models, model) 54 } 55 } 56 return models 57 } 58 59 // Model APIのリクエスト/レスポンスなどのデータ型を示すモデル 60 type Model struct { 61 Name string // 型名 62 Alias string // 型エイリアス(省略可) 63 Fields []*FieldDesc // フィールド定義 64 ConstFields []*ConstFieldDesc // 定数フィールド 65 Methods []*MethodDesc // アクセサ 66 NakedType meta.Type // 対応するnaked型の情報 67 IsArray bool 68 isPointer bool 69 } 70 71 // HasNakedType 対応するnaked型の情報が登録されているか 72 func (m *Model) HasNakedType() bool { 73 return m.NakedType != nil 74 } 75 76 // Type モデルの型情報 77 func (m *Model) Type() meta.Type { 78 return m 79 } 80 81 // GoType 型名 82 func (m *Model) GoType() string { 83 prefix := "" 84 if m.IsArray { 85 prefix = "[]" 86 } 87 88 name := m.Name 89 if m.Alias != "" { 90 name = m.Alias 91 } 92 93 if IsOutOfSacloudPackage { 94 name = "iaas." + name 95 } 96 97 return prefix + name 98 } 99 100 // GoPkg パッケージ名 101 func (m *Model) GoPkg() string { 102 if IsOutOfSacloudPackage { 103 return "sacloud" 104 } 105 return "" 106 } 107 108 // GoImportPath インポートパス 109 func (m *Model) GoImportPath() string { 110 if IsOutOfSacloudPackage { 111 return "github.com/sacloud/iaas-api-go" 112 } 113 return "" 114 } 115 116 // GoTypeSourceCode ソースコードでの型表現 117 func (m *Model) GoTypeSourceCode() string { 118 name := m.Name 119 if m.Alias != "" { 120 name = m.Alias 121 } 122 if IsOutOfSacloudPackage { 123 name = "iaas." + name 124 } 125 if m.IsArray { 126 if m.isPointer { 127 return fmt.Sprintf("*[]*%s", name) 128 } 129 return fmt.Sprintf("[]*%s", name) 130 } 131 if m.Alias != "" { 132 return name 133 } 134 return fmt.Sprintf("*%s", name) 135 } 136 137 // ZeroInitializeSourceCode 型に応じたzero値での初期化コード 138 func (m *Model) ZeroInitializeSourceCode() string { 139 name := m.Name 140 if m.Alias != "" { 141 name = m.Alias 142 } 143 144 if IsOutOfSacloudPackage { 145 name = "iaas." + name 146 } 147 if m.IsArray { 148 if m.isPointer { 149 return fmt.Sprintf("&[]*%s{}", name) 150 } 151 return fmt.Sprintf("[]*%s{}", name) 152 } 153 if m.Alias != "" { 154 return fmt.Sprintf("%s{}", name) 155 } 156 return fmt.Sprintf("&%s{}", name) 157 } 158 159 // ZeroValueSourceCode 型に応じたzero値コード 160 func (m *Model) ZeroValueSourceCode() string { 161 return "nil" 162 } 163 164 // ImportStatements コード生成時に利用するimport文を生成する 165 func (m *Model) ImportStatements(additionalImports ...string) []string { 166 ss := wrapByDoubleQuote(additionalImports...) 167 return uniqStrings(ss) 168 } 169 170 // ImportStatementsForModelDef モデルのフィールドを含めたimport文を生成する 171 func (m *Model) ImportStatementsForModelDef(additionalImports ...string) []string { 172 ss := wrapByDoubleQuote(additionalImports...) 173 for _, f := range m.Fields { 174 s := f.Type.GoImportPath() 175 if s != "" { 176 ss = append(ss, wrapByDoubleQuote(s)[0]) 177 } 178 } 179 return uniqStrings(ss) 180 } 181 182 // FieldModels フィールド定義に含まれる*Model(FieldDesc.Type)を取得 183 func (m *Model) FieldModels() []*Model { 184 var ms []*Model 185 for _, f := range m.Fields { 186 if f.Type == nil { 187 continue 188 } 189 if m, ok := f.Type.(*Model); ok { 190 ms = append(ms, m) 191 ms = append(ms, m.FieldModels()...) 192 } 193 } 194 return ms 195 } 196 197 // ToPtrType ポインタ型への変換 198 func (m *Model) ToPtrType() meta.Type { 199 return &Model{ 200 Name: m.Name, 201 Alias: m.Alias, 202 Fields: m.Fields, 203 ConstFields: m.ConstFields, 204 Methods: m.Methods, 205 NakedType: m.NakedType, 206 IsArray: m.IsArray, 207 isPointer: true, 208 } 209 }