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  }