// Copyright 2022 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package printer

import (
	
	
	
)

// formatDocComment reformats the doc comment list,
// returning the canonical formatting.
func formatDocComment( []*ast.Comment) []*ast.Comment {
	// Extract comment text (removing comment markers).
	var ,  string
	var  []*ast.Comment
	if len() == 1 && strings.HasPrefix([0].Text, "/*") {
		 = "/*"
		 = [0].Text
		if !strings.Contains(, "\n") || allStars() {
			// Single-line /* .. */ comment in doc comment position,
			// or multiline old-style comment like
			//	/*
			//	 * Comment
			//	 * text here.
			//	 */
			// Should not happen, since it will not work well as a
			// doc comment, but if it does, just ignore:
			// reformatting it will only make the situation worse.
			return 
		}
		 = [2 : len()-2] // cut /* and */
	} else if strings.HasPrefix([0].Text, "//") {
		 = "//"
		var  strings.Builder
		for ,  := range  {
			,  := strings.CutPrefix(.Text, "//")
			if ! {
				return 
			}
			// Accumulate //go:build etc lines separately.
			if isDirective() {
				 = append(, )
				continue
			}
			.WriteString(strings.TrimPrefix(, " "))
			.WriteString("\n")
		}
		 = .String()
	} else {
		// Not sure what this is, so leave alone.
		return 
	}

	if  == "" {
		return 
	}

	// Parse comment and reformat as text.
	var  comment.Parser
	 := .Parse()

	var  comment.Printer
	 = string(.Comment())

	// For /* */ comment, return one big comment with text inside.
	 := [0].Slash
	if  == "/*" {
		 := &ast.Comment{
			Slash: ,
			Text:  "/*\n" +  + "*/",
		}
		return []*ast.Comment{}
	}

	// For // comment, return sequence of // lines.
	var  []*ast.Comment
	for  != "" {
		var  string
		, , _ = strings.Cut(, "\n")
		if  == "" {
			 = "//"
		} else if strings.HasPrefix(, "\t") {
			 = "//" + 
		} else {
			 = "// " + 
		}
		 = append(, &ast.Comment{
			Slash: ,
			Text:  ,
		})
	}
	if len() > 0 {
		 = append(, &ast.Comment{
			Slash: ,
			Text:  "//",
		})
		for ,  := range  {
			 = append(, &ast.Comment{
				Slash: ,
				Text:  .Text,
			})
		}
	}
	return 
}

// isDirective reports whether c is a comment directive.
// See go.dev/issue/37974.
// This code is also in go/ast.
func isDirective( string) bool {
	// "//line " is a line directive.
	// "//extern " is for gccgo.
	// "//export " is for cgo.
	// (The // has been removed.)
	if strings.HasPrefix(, "line ") || strings.HasPrefix(, "extern ") || strings.HasPrefix(, "export ") {
		return true
	}

	// "//[a-z0-9]+:[a-z0-9]"
	// (The // has been removed.)
	 := strings.Index(, ":")
	if  <= 0 || +1 >= len() {
		return false
	}
	for  := 0;  <= +1; ++ {
		if  ==  {
			continue
		}
		 := []
		if !('a' <=  &&  <= 'z' || '0' <=  &&  <= '9') {
			return false
		}
	}
	return true
}

// allStars reports whether text is the interior of an
// old-style /* */ comment with a star at the start of each line.
func allStars( string) bool {
	for  := 0;  < len(); ++ {
		if [] == '\n' {
			 :=  + 1
			for  < len() && ([] == ' ' || [] == '\t') {
				++
			}
			if  < len() && [] != '*' {
				return false
			}
		}
	}
	return true
}