github.com/kyma-incubator/compass/components/director@v0.0.0-20230623144113-d764f56ff805/hack/plugins/formatter.go (about)

     1  /*
     2  Part of this file is copied from https://github.com/vektah/gqlparser/blob/master/formatter/formatter.go.
     3  Below you can find its licence.
     4  
     5  Copyright (c) 2018 Adam Scarr
     6  
     7  Permission is hereby granted, free of charge, to any person obtaining a copy
     8  of this software and associated documentation files (the "Software"), to deal
     9  in the Software without restriction, including without limitation the rights
    10  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    11  copies of the Software, and to permit persons to whom the Software is
    12  furnished to do so, subject to the following conditions:
    13  
    14  The above copyright notice and this permission notice shall be included in all
    15  copies or substantial portions of the Software.
    16  
    17  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    18  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    19  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    20  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    21  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    22  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
    23  SOFTWARE.
    24  */
    25  package plugins
    26  
    27  import (
    28  	"fmt"
    29  	"io"
    30  	"sort"
    31  	"strings"
    32  
    33  	"github.com/vektah/gqlparser/v2/ast"
    34  )
    35  
    36  // Formatter missing godoc
    37  type Formatter interface {
    38  	FormatSchema(schema *ast.Schema)
    39  }
    40  
    41  // NewFormatter missing godoc
    42  func NewFormatter(w io.Writer) Formatter {
    43  	return &formatter{writer: w}
    44  }
    45  
    46  type formatter struct {
    47  	writer io.Writer
    48  
    49  	indent      int
    50  	emitBuiltin bool
    51  
    52  	padNext  bool
    53  	lineHead bool
    54  }
    55  
    56  func (f *formatter) writeString(s string) {
    57  	_, err := f.writer.Write([]byte(s))
    58  	if err != nil {
    59  		panic(err)
    60  	}
    61  }
    62  
    63  func (f *formatter) WriteIndent() *formatter {
    64  	if f.lineHead {
    65  		f.writeString(strings.Repeat("\t", f.indent))
    66  	}
    67  	f.lineHead = false
    68  	f.padNext = false
    69  
    70  	return f
    71  }
    72  
    73  // WriteNewline missing godoc
    74  func (f *formatter) WriteNewline() *formatter {
    75  	f.writeString("\n")
    76  	f.lineHead = true
    77  	f.padNext = false
    78  
    79  	return f
    80  }
    81  
    82  // WriteWord missing godoc
    83  func (f *formatter) WriteWord(word string) *formatter {
    84  	if f.lineHead {
    85  		f.WriteIndent()
    86  	}
    87  	if f.padNext {
    88  		f.writeString(" ")
    89  	}
    90  	f.writeString(strings.TrimSpace(word))
    91  	f.padNext = true
    92  
    93  	return f
    94  }
    95  
    96  // WriteString missing godoc
    97  func (f *formatter) WriteString(s string) *formatter {
    98  	if f.lineHead {
    99  		f.WriteIndent()
   100  	}
   101  	if f.padNext {
   102  		f.writeString(" ")
   103  	}
   104  	f.writeString(s)
   105  	f.padNext = false
   106  
   107  	return f
   108  }
   109  
   110  // WriteDescription missing godoc
   111  func (f *formatter) WriteDescription(s string) *formatter {
   112  	if s == "" {
   113  		return f
   114  	}
   115  
   116  	f.WriteString(`"""`).WriteNewline()
   117  
   118  	ss := strings.Split(s, "\n")
   119  	for _, s := range ss {
   120  		f.WriteString(s).WriteNewline()
   121  	}
   122  
   123  	f.WriteString(`"""`).WriteNewline()
   124  
   125  	return f
   126  }
   127  
   128  // IncrementIndent missing godoc
   129  func (f *formatter) IncrementIndent() {
   130  	f.indent++
   131  }
   132  
   133  // DecrementIndent missing godoc
   134  func (f *formatter) DecrementIndent() {
   135  	f.indent--
   136  }
   137  
   138  // NoPadding missing godoc
   139  func (f *formatter) NoPadding() *formatter {
   140  	f.padNext = false
   141  
   142  	return f
   143  }
   144  
   145  // NeedPadding missing godoc
   146  func (f *formatter) NeedPadding() *formatter {
   147  	f.padNext = true
   148  
   149  	return f
   150  }
   151  
   152  // FormatSchema missing godoc
   153  func (f *formatter) FormatSchema(schema *ast.Schema) {
   154  	if schema == nil {
   155  		return
   156  	}
   157  
   158  	var inSchema bool
   159  	startSchema := func() {
   160  		if !inSchema {
   161  			inSchema = true
   162  
   163  			f.WriteWord("schema").WriteString("{").WriteNewline()
   164  			f.IncrementIndent()
   165  		}
   166  	}
   167  	if schema.Query != nil && schema.Query.Name != "Query" {
   168  		startSchema()
   169  		f.WriteWord("query").NoPadding().WriteString(":").NeedPadding()
   170  		f.WriteWord(schema.Query.Name).WriteNewline()
   171  	}
   172  	if schema.Mutation != nil && schema.Mutation.Name != "Mutation" {
   173  		startSchema()
   174  		f.WriteWord("mutation").NoPadding().WriteString(":").NeedPadding()
   175  		f.WriteWord(schema.Mutation.Name).WriteNewline()
   176  	}
   177  	if schema.Subscription != nil && schema.Subscription.Name != "Subscription" {
   178  		startSchema()
   179  		f.WriteWord("subscription").NoPadding().WriteString(":").NeedPadding()
   180  		f.WriteWord(schema.Subscription.Name).WriteNewline()
   181  	}
   182  	if inSchema {
   183  		f.DecrementIndent()
   184  		f.WriteString("}").WriteNewline()
   185  	}
   186  
   187  	directiveNames := make([]string, 0, len(schema.Directives))
   188  	for name := range schema.Directives {
   189  		directiveNames = append(directiveNames, name)
   190  	}
   191  	sort.Strings(directiveNames)
   192  	for _, name := range directiveNames {
   193  		f.FormatDirectiveDefinition(schema.Directives[name])
   194  	}
   195  
   196  	var dl OrderedDefinitionList
   197  	for _, v := range schema.Types {
   198  		dl = append(dl, *v)
   199  	}
   200  
   201  	sort.Sort(dl)
   202  
   203  	for _, t := range dl {
   204  		f.FormatDefinition(&t, false)
   205  	}
   206  }
   207  
   208  // FormatFieldList missing godoc
   209  func (f *formatter) FormatFieldList(fieldList ast.FieldList) {
   210  	if len(fieldList) == 0 {
   211  		return
   212  	}
   213  
   214  	f.WriteString("{").WriteNewline()
   215  	f.IncrementIndent()
   216  
   217  	for _, field := range fieldList {
   218  		f.FormatFieldDefinition(field)
   219  	}
   220  
   221  	f.DecrementIndent()
   222  	f.WriteString("}")
   223  }
   224  
   225  // FormatFieldDefinition missing godoc
   226  func (f *formatter) FormatFieldDefinition(field *ast.FieldDefinition) {
   227  	if !f.emitBuiltin && strings.HasPrefix(field.Name, "__") {
   228  		return
   229  	}
   230  
   231  	f.WriteDescription(field.Description)
   232  
   233  	f.WriteWord(field.Name).NoPadding()
   234  	f.FormatArgumentDefinitionList(field.Arguments)
   235  	f.NoPadding().WriteString(":").NeedPadding()
   236  	f.FormatType(field.Type)
   237  
   238  	if field.DefaultValue != nil {
   239  		f.WriteWord("=")
   240  		f.FormatValue(field.DefaultValue)
   241  	}
   242  
   243  	f.FormatDirectiveList(field.Directives)
   244  
   245  	f.WriteNewline()
   246  }
   247  
   248  // FormatArgumentDefinitionList missing godoc
   249  func (f *formatter) FormatArgumentDefinitionList(lists ast.ArgumentDefinitionList) {
   250  	if len(lists) == 0 {
   251  		return
   252  	}
   253  
   254  	f.WriteString("(")
   255  	for idx, arg := range lists {
   256  		f.FormatArgumentDefinition(arg)
   257  
   258  		if idx != len(lists)-1 {
   259  			f.NoPadding().WriteWord(",")
   260  		}
   261  	}
   262  	f.NoPadding().WriteString(")").NeedPadding()
   263  }
   264  
   265  // FormatArgumentDefinition missing godoc
   266  func (f *formatter) FormatArgumentDefinition(def *ast.ArgumentDefinition) {
   267  	f.WriteDescription(def.Description)
   268  
   269  	f.WriteWord(def.Name).NoPadding().WriteString(":").NeedPadding()
   270  	f.FormatType(def.Type)
   271  
   272  	if def.DefaultValue != nil {
   273  		f.WriteWord("=")
   274  		f.FormatValue(def.DefaultValue)
   275  	}
   276  
   277  	f.FormatDirectiveList(def.Directives)
   278  }
   279  
   280  // FormatDirectiveLocation missing godoc
   281  func (f *formatter) FormatDirectiveLocation(location ast.DirectiveLocation) {
   282  	f.WriteWord(string(location))
   283  }
   284  
   285  // FormatDirectiveDefinitionList missing godoc
   286  func (f *formatter) FormatDirectiveDefinitionList(lists ast.DirectiveDefinitionList) {
   287  	if len(lists) == 0 {
   288  		return
   289  	}
   290  
   291  	for _, dec := range lists {
   292  		f.FormatDirectiveDefinition(dec)
   293  	}
   294  }
   295  
   296  // FormatDirectiveDefinition missing godoc
   297  func (f *formatter) FormatDirectiveDefinition(def *ast.DirectiveDefinition) {
   298  	if !f.emitBuiltin {
   299  		if def.Position.Src.BuiltIn {
   300  			return
   301  		}
   302  	}
   303  
   304  	f.WriteDescription(def.Description)
   305  	f.WriteWord("directive").WriteString("@").WriteWord(def.Name)
   306  
   307  	if len(def.Arguments) != 0 {
   308  		f.NoPadding()
   309  		f.FormatArgumentDefinitionList(def.Arguments)
   310  	}
   311  
   312  	if len(def.Locations) != 0 {
   313  		f.WriteWord("on")
   314  
   315  		for idx, dirLoc := range def.Locations {
   316  			f.FormatDirectiveLocation(dirLoc)
   317  
   318  			if idx != len(def.Locations)-1 {
   319  				f.WriteWord("|")
   320  			}
   321  		}
   322  	}
   323  
   324  	f.WriteNewline()
   325  }
   326  
   327  // FormatDefinition missing godoc
   328  func (f *formatter) FormatDefinition(def *ast.Definition, extend bool) {
   329  	if !f.emitBuiltin && def.BuiltIn {
   330  		return
   331  	}
   332  
   333  	f.WriteDescription(def.Description)
   334  
   335  	if extend {
   336  		f.WriteWord("extend")
   337  	}
   338  
   339  	switch def.Kind {
   340  	case ast.Scalar:
   341  		f.WriteWord("scalar").WriteWord(def.Name)
   342  
   343  	case ast.Object:
   344  		f.WriteWord("type").WriteWord(def.Name)
   345  
   346  	case ast.Interface:
   347  		f.WriteWord("interface").WriteWord(def.Name)
   348  
   349  	case ast.Union:
   350  		f.WriteWord("union").WriteWord(def.Name)
   351  
   352  	case ast.Enum:
   353  		f.WriteWord("enum").WriteWord(def.Name)
   354  
   355  	case ast.InputObject:
   356  		f.WriteWord("input").WriteWord(def.Name)
   357  	}
   358  
   359  	f.FormatDirectiveList(def.Directives)
   360  
   361  	if len(def.Types) != 0 {
   362  		f.WriteWord("=").WriteWord(strings.Join(def.Types, " | "))
   363  	}
   364  
   365  	if len(def.Interfaces) != 0 {
   366  		f.WriteWord("implements").WriteWord(strings.Join(def.Interfaces, ", "))
   367  	}
   368  
   369  	f.FormatFieldList(def.Fields)
   370  
   371  	f.FormatEnumValueList(def.EnumValues)
   372  
   373  	f.WriteNewline()
   374  	f.WriteNewline()
   375  }
   376  
   377  // FormatEnumValueList missing godoc
   378  func (f *formatter) FormatEnumValueList(lists ast.EnumValueList) {
   379  	if len(lists) == 0 {
   380  		return
   381  	}
   382  
   383  	f.WriteString("{").WriteNewline()
   384  	f.IncrementIndent()
   385  
   386  	for _, v := range lists {
   387  		f.FormatEnumValueDefinition(v)
   388  	}
   389  
   390  	f.DecrementIndent()
   391  	f.WriteString("}")
   392  }
   393  
   394  // FormatEnumValueDefinition missing godoc
   395  func (f *formatter) FormatEnumValueDefinition(def *ast.EnumValueDefinition) {
   396  	f.WriteDescription(def.Description)
   397  
   398  	f.WriteWord(def.Name)
   399  	f.FormatDirectiveList(def.Directives)
   400  
   401  	f.WriteNewline()
   402  }
   403  
   404  // FormatDirectiveList missing godoc
   405  func (f *formatter) FormatDirectiveList(lists ast.DirectiveList) {
   406  	if len(lists) == 0 {
   407  		return
   408  	}
   409  
   410  	for _, dir := range lists {
   411  		f.FormatDirective(dir)
   412  	}
   413  }
   414  
   415  // FormatDirective missing godoc
   416  func (f *formatter) FormatDirective(dir *ast.Directive) {
   417  	f.WriteString("@").WriteWord(dir.Name)
   418  	f.FormatArgumentList(dir.Arguments)
   419  }
   420  
   421  // FormatArgumentList missing godoc
   422  func (f *formatter) FormatArgumentList(lists ast.ArgumentList) {
   423  	if len(lists) == 0 {
   424  		return
   425  	}
   426  	f.NoPadding().WriteString("(")
   427  	for idx, arg := range lists {
   428  		f.FormatArgument(arg)
   429  
   430  		if idx != len(lists)-1 {
   431  			f.NoPadding().WriteWord(",")
   432  		}
   433  	}
   434  	f.WriteString(")").NeedPadding()
   435  }
   436  
   437  // FormatArgument missing godoc
   438  func (f *formatter) FormatArgument(arg *ast.Argument) {
   439  	f.WriteWord(arg.Name).NoPadding().WriteString(":").NeedPadding()
   440  	f.WriteString(arg.Value.String())
   441  }
   442  
   443  // FormatSelectionSet missing godoc
   444  func (f *formatter) FormatSelectionSet(sets ast.SelectionSet) {
   445  	if len(sets) == 0 {
   446  		return
   447  	}
   448  
   449  	f.WriteString("{").WriteNewline()
   450  	f.IncrementIndent()
   451  
   452  	for _, sel := range sets {
   453  		f.FormatSelection(sel)
   454  	}
   455  
   456  	f.DecrementIndent()
   457  	f.WriteString("}")
   458  }
   459  
   460  // FormatSelection missing godoc
   461  func (f *formatter) FormatSelection(selection ast.Selection) {
   462  	switch v := selection.(type) {
   463  	case *ast.Field:
   464  		f.FormatField(v)
   465  
   466  	case *ast.FragmentSpread:
   467  		f.FormatFragmentSpread(v)
   468  
   469  	case *ast.InlineFragment:
   470  		f.FormatInlineFragment(v)
   471  
   472  	default:
   473  		panic(fmt.Errorf("unknown Selection type: %T", selection))
   474  	}
   475  
   476  	f.WriteNewline()
   477  }
   478  
   479  // FormatField missing godoc
   480  func (f *formatter) FormatField(field *ast.Field) {
   481  	if field.Alias != "" && field.Alias != field.Name {
   482  		f.WriteWord(field.Alias).NoPadding().WriteString(":").NeedPadding()
   483  	}
   484  	f.WriteWord(field.Name)
   485  
   486  	if len(field.Arguments) != 0 {
   487  		f.NoPadding()
   488  		f.FormatArgumentList(field.Arguments)
   489  		f.NeedPadding()
   490  	}
   491  
   492  	f.FormatDirectiveList(field.Directives)
   493  
   494  	f.FormatSelectionSet(field.SelectionSet)
   495  }
   496  
   497  // FormatFragmentSpread missing godoc
   498  func (f *formatter) FormatFragmentSpread(spread *ast.FragmentSpread) {
   499  	f.WriteWord("...").WriteWord(spread.Name)
   500  
   501  	f.FormatDirectiveList(spread.Directives)
   502  }
   503  
   504  // FormatInlineFragment missing godoc
   505  func (f *formatter) FormatInlineFragment(inline *ast.InlineFragment) {
   506  	f.WriteWord("...")
   507  	if inline.TypeCondition != "" {
   508  		f.WriteWord("on").WriteWord(inline.TypeCondition)
   509  	}
   510  
   511  	f.FormatDirectiveList(inline.Directives)
   512  
   513  	f.FormatSelectionSet(inline.SelectionSet)
   514  }
   515  
   516  // FormatType missing godoc
   517  func (f *formatter) FormatType(t *ast.Type) {
   518  	f.WriteWord(t.String())
   519  }
   520  
   521  // FormatValue missing godoc
   522  func (f *formatter) FormatValue(value *ast.Value) {
   523  	f.WriteString(value.String())
   524  }