1// Copyright 2019 Istio 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 15package codegen 16 17import ( 18 "bytes" 19 "strings" 20 "text/template" 21) 22 23const ( 24 commentLinePrefix = "// " 25) 26 27func applyTemplate(tmpl string, i interface{}) (string, error) { 28 t := template.New("tmpl").Funcs(template.FuncMap{ 29 "wordWrap": wordWrap, 30 "commentBlock": commentBlock, 31 "hasPrefix": strings.HasPrefix, 32 }) 33 34 t2 := template.Must(t.Parse(tmpl)) 35 36 var b bytes.Buffer 37 if err := t2.Execute(&b, i); err != nil { 38 return "", err 39 } 40 41 return b.String(), nil 42} 43 44func commentBlock(in []string, indentTabs int) string { 45 // Copy the input array. 46 in = append([]string{}, in...) 47 48 // Apply the tabs and comment prefix to each line. 49 for lineIndex := range in { 50 prefix := "" 51 for tabIndex := 0; lineIndex > 0 && tabIndex < indentTabs; tabIndex++ { 52 prefix += "\t" 53 } 54 prefix += commentLinePrefix 55 in[lineIndex] = prefix + in[lineIndex] 56 } 57 58 // Join the lines with carriage returns. 59 return strings.Join(in, "\n") 60} 61 62func wordWrap(in string, maxLineLength int) []string { 63 // First, split the input based on any user-created lines (i.e. the string contains "\n"). 64 inputLines := strings.Split(in, "\n") 65 outputLines := make([]string, 0) 66 67 line := "" 68 for i, inputLine := range inputLines { 69 if i > 0 { 70 // Process a user-defined carriage return. 71 outputLines = append(outputLines, line) 72 line = "" 73 } 74 75 words := strings.Split(inputLine, " ") 76 77 for len(words) > 0 { 78 // Take the next word. 79 word := words[0] 80 words = words[1:] 81 82 if len(line)+len(word) > maxLineLength { 83 // Need to word wrap - emit the current line. 84 outputLines = append(outputLines, line) 85 line = "" 86 } 87 88 // Add the word to the current line. 89 if len(line) > 0 { 90 line += " " 91 } 92 line += word 93 } 94 } 95 96 // Emit the final line 97 outputLines = append(outputLines, line) 98 99 return outputLines 100} 101