github.com/cloudwego/kitex@v0.9.0/tool/internal_pkg/generator/template.go (about)

     1  // Copyright 2022 CloudWeGo 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 generator
    16  
    17  import (
    18  	"encoding/json"
    19  	"fmt"
    20  	"io/ioutil"
    21  
    22  	"gopkg.in/yaml.v3"
    23  )
    24  
    25  // APIExtension contains segments to extend an API template.
    26  type APIExtension struct {
    27  	// ImportPaths contains a list of import path that the file should add to the import list.
    28  	// The paths must be registered with the TemplateExtension's Dependencies fields.
    29  	ImportPaths []string `json:"import_paths,omitempty" yaml:"import_paths,omitempty"`
    30  
    31  	// Code snippets to be inserted in the NewX function before assembling options.
    32  	// It must be a template definition with a name identical to the one kitex uses.
    33  	ExtendOption string `json:"extend_option,omitempty" yaml:"extend_option,omitempty"`
    34  
    35  	// Code snippets to be appended to the file.
    36  	// It must be a template definition with a name identical to the one kitex uses.
    37  	ExtendFile string `json:"extend_file,omitempty" yaml:"extend_file,omitempty"`
    38  }
    39  
    40  // TemplateExtension extends templates that generates files in *service packages.
    41  type TemplateExtension struct {
    42  	// FeatureNames registers some names to the scope for the code generating phrase, where templates can use the `HasFeature` function to query.
    43  	FeatureNames []string `json:"feature_names,omitempty" yaml:"feature_names,omitempty"`
    44  
    45  	// EnableFeatures marks on which features that `HasFeature` queries should return true.
    46  	EnableFeatures []string `json:"enable_features,omitempty" yaml:"enable_features,omitempty"`
    47  
    48  	// Dependencies is a mapping from import path to package names/aliases.
    49  	Dependencies map[string]string `json:"dependencies,omitempty" yaml:"dependencies,omitempty"`
    50  
    51  	// Extension for client.go .
    52  	ExtendClient *APIExtension `json:"extend_client,omitempty" yaml:"extend_client,omitempty"`
    53  
    54  	// Extension for server.go .
    55  	ExtendServer *APIExtension `json:"extend_server,omitempty" yaml:"extend_server,omitempty"`
    56  
    57  	// Extension for invoker.go .
    58  	ExtendInvoker *APIExtension `json:"extend_invoker,omitempty" yaml:"extend_invoker,omitempty"`
    59  }
    60  
    61  // FromJSONFile unmarshals a TemplateExtension with JSON format from the given file.
    62  func (p *TemplateExtension) FromJSONFile(filename string) error {
    63  	if p == nil {
    64  		return nil
    65  	}
    66  	data, err := ioutil.ReadFile(filename)
    67  	if err != nil {
    68  		return err
    69  	}
    70  	return json.Unmarshal(data, p)
    71  }
    72  
    73  // ToJSONFile marshals a TemplateExtension to the given file in JSON format.
    74  func (p *TemplateExtension) ToJSONFile(filename string) error {
    75  	data, err := json.Marshal(p)
    76  	if err != nil {
    77  		return err
    78  	}
    79  	return ioutil.WriteFile(filename, data, 0o644)
    80  }
    81  
    82  // FromYAMLFile unmarshals a TemplateExtension with YAML format from the given file.
    83  func (p *TemplateExtension) FromYAMLFile(filename string) error {
    84  	if p == nil {
    85  		return nil
    86  	}
    87  	data, err := ioutil.ReadFile(filename)
    88  	if err != nil {
    89  		return err
    90  	}
    91  	return yaml.Unmarshal(data, p)
    92  }
    93  
    94  func (p *TemplateExtension) ToYAMLFile(filename string) error {
    95  	data, err := yaml.Marshal(p)
    96  	if err != nil {
    97  		return err
    98  	}
    99  	return ioutil.WriteFile(filename, data, 0o644)
   100  }
   101  
   102  func (p *TemplateExtension) Merge(other *TemplateExtension) {
   103  	if other == nil {
   104  		return
   105  	}
   106  	p.FeatureNames = append(p.FeatureNames, other.FeatureNames...)
   107  	p.EnableFeatures = append(p.EnableFeatures, other.EnableFeatures...)
   108  
   109  	if other.Dependencies != nil {
   110  		if p.Dependencies == nil {
   111  			p.Dependencies = other.Dependencies
   112  		} else {
   113  			for k, v := range other.Dependencies {
   114  				p.Dependencies[k] = v
   115  			}
   116  		}
   117  	}
   118  
   119  	if other.ExtendClient != nil {
   120  		if p.ExtendClient == nil {
   121  			p.ExtendClient = other.ExtendClient
   122  		} else {
   123  			p.ExtendClient.Merge(other.ExtendClient)
   124  		}
   125  	}
   126  	if other.ExtendServer != nil {
   127  		if p.ExtendServer == nil {
   128  			p.ExtendServer = other.ExtendServer
   129  		} else {
   130  			p.ExtendServer.Merge(other.ExtendServer)
   131  		}
   132  	}
   133  	if other.ExtendInvoker != nil {
   134  		if p.ExtendInvoker == nil {
   135  			p.ExtendInvoker = other.ExtendInvoker
   136  		} else {
   137  			p.ExtendInvoker.Merge(other.ExtendInvoker)
   138  		}
   139  	}
   140  }
   141  
   142  func (a *APIExtension) Merge(other *APIExtension) {
   143  	if other == nil {
   144  		return
   145  	}
   146  	a.ImportPaths = append(a.ImportPaths, other.ImportPaths...)
   147  	a.ExtendOption = fmt.Sprintf("%v\n%v", a.ExtendOption, other.ExtendOption)
   148  	a.ExtendFile = fmt.Sprintf("%v\n%v", a.ExtendFile, other.ExtendFile)
   149  }