github.com/authzed/spicedb@v1.32.1-0.20240520085336-ebda56537386/pkg/schemadsl/generator/generator_impl.go (about)

     1  package generator
     2  
     3  import (
     4  	"strings"
     5  )
     6  
     7  type sourceGenerator struct {
     8  	buf                strings.Builder // The buffer for the new source code.
     9  	indentationLevel   int             // The current indentation level.
    10  	hasNewline         bool            // Whether there is a newline at the end of the buffer.
    11  	hasBlankline       bool            // Whether there is a blank line at the end of the buffer.
    12  	hasIssue           bool            // Whether there is a translation issue.
    13  	hasNewScope        bool            // Whether there is a new scope at the end of the buffer.
    14  	existingLineLength int             // Length of the existing line.
    15  }
    16  
    17  // ensureBlankLineOrNewScope ensures that there is a blank line or new scope at the tail of the buffer. If not,
    18  // a new line is added.
    19  func (sg *sourceGenerator) ensureBlankLineOrNewScope() {
    20  	if !sg.hasBlankline && !sg.hasNewScope {
    21  		sg.appendLine()
    22  	}
    23  }
    24  
    25  // indent increases the current indentation.
    26  func (sg *sourceGenerator) indent() {
    27  	sg.indentationLevel = sg.indentationLevel + 1
    28  }
    29  
    30  // dedent decreases the current indentation.
    31  func (sg *sourceGenerator) dedent() {
    32  	sg.indentationLevel = sg.indentationLevel - 1
    33  }
    34  
    35  // appendIssue adds an issue found in generation.
    36  func (sg *sourceGenerator) appendIssue(description string) {
    37  	sg.append("/* ")
    38  	sg.append(description)
    39  	sg.append(" */")
    40  	sg.hasIssue = true
    41  }
    42  
    43  // append adds the given value to the buffer, indenting as necessary.
    44  func (sg *sourceGenerator) append(value string) {
    45  	for _, currentRune := range value {
    46  		if currentRune == '\n' {
    47  			if sg.hasNewline {
    48  				sg.hasBlankline = true
    49  			}
    50  
    51  			sg.buf.WriteRune('\n')
    52  			sg.hasNewline = true
    53  			sg.existingLineLength = 0
    54  			continue
    55  		}
    56  
    57  		sg.hasBlankline = false
    58  		sg.hasNewScope = false
    59  
    60  		if sg.hasNewline {
    61  			sg.buf.WriteString(strings.Repeat("\t", sg.indentationLevel))
    62  			sg.hasNewline = false
    63  			sg.existingLineLength += sg.indentationLevel
    64  		}
    65  
    66  		sg.existingLineLength++
    67  		sg.buf.WriteRune(currentRune)
    68  	}
    69  }
    70  
    71  // appendLine adds a newline.
    72  func (sg *sourceGenerator) appendLine() {
    73  	sg.append("\n")
    74  }
    75  
    76  func (sg *sourceGenerator) markNewScope() {
    77  	sg.hasNewScope = true
    78  }