// Copyright 2017 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 message

import (
	
	 // TODO: consider copying interfaces from package fmt to avoid dependency.
	
	
	
	

	
	
	
	
)

// Strings for use with buffer.WriteString.
// This is less overhead than using buffer.Write with byte arrays.
const (
	commaSpaceString  = ", "
	nilAngleString    = "<nil>"
	nilParenString    = "(nil)"
	nilString         = "nil"
	mapString         = "map["
	percentBangString = "%!"
	missingString     = "(MISSING)"
	badIndexString    = "(BADINDEX)"
	panicString       = "(PANIC="
	extraString       = "%!(EXTRA "
	badWidthString    = "%!(BADWIDTH)"
	badPrecString     = "%!(BADPREC)"
	noVerbString      = "%!(NOVERB)"

	invReflectString = "<invalid reflect.Value>"
)

var printerPool = sync.Pool{
	New: func() interface{} { return new(printer) },
}

// newPrinter allocates a new printer struct or grabs a cached one.
func newPrinter( *Printer) *printer {
	 := printerPool.Get().(*printer)
	.Printer = *
	// TODO: cache most of the following call.
	.catContext = .cat.Context(.tag, )

	.panicking = false
	.erroring = false
	.fmt.init(&.Buffer)
	return 
}

// free saves used printer structs in printerFree; avoids an allocation per invocation.
func ( *printer) () {
	.Buffer.Reset()
	.arg = nil
	.value = reflect.Value{}
	printerPool.Put()
}

// printer is used to store a printer's state.
// It implements "golang.org/x/text/internal/format".State.
type printer struct {
	Printer

	// the context for looking up message translations
	catContext *catalog.Context

	// buffer for accumulating output.
	bytes.Buffer

	// arg holds the current item, as an interface{}.
	arg interface{}
	// value is used instead of arg for reflect values.
	value reflect.Value

	// fmt is used to format basic items such as integers or strings.
	fmt formatInfo

	// panicking is set by catchPanic to avoid infinite panic, recover, panic, ... recursion.
	panicking bool
	// erroring is set when printing an error string to guard against calling handleMethods.
	erroring bool
}

// Language implements "golang.org/x/text/internal/format".State.
func ( *printer) () language.Tag { return .tag }

func ( *printer) () ( int,  bool) { return .fmt.Width, .fmt.WidthPresent }

func ( *printer) () ( int,  bool) { return .fmt.Prec, .fmt.PrecPresent }

func ( *printer) ( int) bool {
	switch  {
	case '-':
		return .fmt.Minus
	case '+':
		return .fmt.Plus || .fmt.PlusV
	case '#':
		return .fmt.Sharp || .fmt.SharpV
	case ' ':
		return .fmt.Space
	case '0':
		return .fmt.Zero
	}
	return false
}

// getField gets the i'th field of the struct value.
// If the field is itself is an interface, return a value for
// the thing inside the interface, not the interface itself.
func getField( reflect.Value,  int) reflect.Value {
	 := .Field()
	if .Kind() == reflect.Interface && !.IsNil() {
		 = .Elem()
	}
	return 
}

func ( *printer) ( reflect.Value) {
	if !.IsValid() {
		.WriteString(nilAngleString)
		return
	}
	.WriteByte('?')
	.WriteString(.Type().String())
	.WriteByte('?')
}

func ( *printer) ( rune) {
	.erroring = true
	.WriteString(percentBangString)
	.WriteRune()
	.WriteByte('(')
	switch {
	case .arg != nil:
		.WriteString(reflect.TypeOf(.arg).String())
		.WriteByte('=')
		.printArg(.arg, 'v')
	case .value.IsValid():
		.WriteString(.value.Type().String())
		.WriteByte('=')
		.printValue(.value, 'v', 0)
	default:
		.WriteString(nilAngleString)
	}
	.WriteByte(')')
	.erroring = false
}

func ( *printer) ( bool,  rune) {
	switch  {
	case 't', 'v':
		.fmt.fmt_boolean()
	default:
		.badVerb()
	}
}

// fmt0x64 formats a uint64 in hexadecimal and prefixes it with 0x or
// not, as requested, by temporarily setting the sharp flag.
func ( *printer) ( uint64,  bool) {
	 := .fmt.Sharp
	.fmt.Sharp = 
	.fmt.fmt_integer(, 16, unsigned, ldigits)
	.fmt.Sharp = 
}

// fmtInteger formats a signed or unsigned integer.
func ( *printer) ( uint64,  bool,  rune) {
	switch  {
	case 'v':
		if .fmt.SharpV && ! {
			.fmt0x64(, true)
			return
		}
		fallthrough
	case 'd':
		if .fmt.Sharp || .fmt.SharpV {
			.fmt.fmt_integer(, 10, , ldigits)
		} else {
			.fmtDecimalInt(, )
		}
	case 'b':
		.fmt.fmt_integer(, 2, , ldigits)
	case 'o':
		.fmt.fmt_integer(, 8, , ldigits)
	case 'x':
		.fmt.fmt_integer(, 16, , ldigits)
	case 'X':
		.fmt.fmt_integer(, 16, , udigits)
	case 'c':
		.fmt.fmt_c()
	case 'q':
		if  <= utf8.MaxRune {
			.fmt.fmt_qc()
		} else {
			.badVerb()
		}
	case 'U':
		.fmt.fmt_unicode()
	default:
		.badVerb()
	}
}

// fmtFloat formats a float. The default precision for each verb
// is specified as last argument in the call to fmt_float.
func ( *printer) ( float64,  int,  rune) {
	switch  {
	case 'b':
		.fmt.fmt_float(, , , -1)
	case 'v':
		 = 'g'
		fallthrough
	case 'g', 'G':
		if .fmt.Sharp || .fmt.SharpV {
			.fmt.fmt_float(, , , -1)
		} else {
			.fmtVariableFloat(, )
		}
	case 'e', 'E':
		if .fmt.Sharp || .fmt.SharpV {
			.fmt.fmt_float(, , , 6)
		} else {
			.fmtScientific(, , 6)
		}
	case 'f', 'F':
		if .fmt.Sharp || .fmt.SharpV {
			.fmt.fmt_float(, , , 6)
		} else {
			.fmtDecimalFloat(, , 6)
		}
	default:
		.badVerb()
	}
}

func ( *printer) ( *number.Formatter) {
	.Flags &^= number.ElideSign
	if .fmt.Plus || .fmt.Space {
		.Flags |= number.AlwaysSign
		if !.fmt.Plus {
			.Flags |= number.ElideSign
		}
	} else {
		.Flags &^= number.AlwaysSign
	}
}

func ( *printer) ( *number.Formatter) {
	.Flags &^= number.PadMask
	if .fmt.Minus {
		.Flags |= number.PadAfterSuffix
	} else {
		.Flags |= number.PadBeforePrefix
	}
	.PadRune = ' '
	.FormatWidth = uint16(.fmt.Width)
}

func ( *printer) (,  int) {
	 := &.toDecimal
	.MinIntegerDigits = 1
	.MaxIntegerDigits = 0
	.MinFractionDigits = uint8()
	.MaxFractionDigits = int16()
	.setFlags()
	.PadRune = 0
	if .fmt.WidthPresent {
		if .fmt.Zero {
			 := .fmt.Width
			// Use significant integers for this.
			// TODO: this is not the same as width, but so be it.
			if .MinFractionDigits > 0 {
				 -= 1 + int(.MinFractionDigits)
			}
			if .fmt.Plus || .fmt.Space {
				--
			}
			if  > 0 &&  > int(.MinIntegerDigits) {
				.MinIntegerDigits = uint8()
			}
		}
		.updatePadding()
	}
}

func ( *printer) (,  int) {
	 := &.toScientific
	if  < 0 {
		.SetPrecision()
	} else {
		.SetPrecision( + 1)
		.MinFractionDigits = uint8()
		.MaxFractionDigits = int16()
	}
	.MinExponentDigits = 2
	.setFlags()
	.PadRune = 0
	if .fmt.WidthPresent {
		.Flags &^= number.PadMask
		if .fmt.Zero {
			.PadRune = .Digit(0)
			.Flags |= number.PadAfterPrefix
		} else {
			.PadRune = ' '
			.Flags |= number.PadBeforePrefix
		}
		.updatePadding()
	}
}

func ( *printer) ( uint64,  bool) {
	var  number.Decimal

	 := &.toDecimal
	if .fmt.PrecPresent {
		.setFlags()
		.MinIntegerDigits = uint8(.fmt.Prec)
		.MaxIntegerDigits = 0
		.MinFractionDigits = 0
		.MaxFractionDigits = 0
		if .fmt.WidthPresent {
			.updatePadding()
		}
	} else {
		.initDecimal(0, 0)
	}
	.ConvertInt(.toDecimal.RoundingContext, , )

	 := .toDecimal.Format([]byte(nil), &)
	.Buffer.Write()
}

func ( *printer) ( float64, ,  int) {
	var  number.Decimal
	if .fmt.PrecPresent {
		 = .fmt.Prec
	}
	.initDecimal(, )
	.ConvertFloat(.toDecimal.RoundingContext, , )

	 := .toDecimal.Format([]byte(nil), &)
	.Buffer.Write()
}

func ( *printer) ( float64,  int) {
	 := -1
	if .fmt.PrecPresent {
		 = .fmt.Prec
	}
	var  number.Decimal
	.initScientific(0, )
	.ConvertFloat(.toScientific.RoundingContext, , )

	// Copy logic of 'g' formatting from strconv. It is simplified a bit as
	// we don't have to mind having prec > len(d.Digits).
	 :=  < 0
	 := 
	if  {
		 = len(.Digits)
		 = 6
	} else if  == 0 {
		 = 1
		 = 1
	}
	 := int(.Exp) - 1
	if  < -4 ||  >=  {
		.initScientific(0, )

		 := .toScientific.Format([]byte(nil), &)
		.Buffer.Write()
	} else {
		if  > int(.Exp) {
			 = len(.Digits)
		}
		if  -= int(.Exp);  < 0 {
			 = 0
		}
		.initDecimal(0, )

		 := .toDecimal.Format([]byte(nil), &)
		.Buffer.Write()
	}
}

func ( *printer) ( float64, ,  int) {
	var  number.Decimal
	if .fmt.PrecPresent {
		 = .fmt.Prec
	}
	.initScientific(, )
	 := .toScientific.RoundingContext
	.ConvertFloat(, , )

	 := .toScientific.Format([]byte(nil), &)
	.Buffer.Write()

}

// fmtComplex formats a complex number v with
// r = real(v) and j = imag(v) as (r+ji) using
// fmtFloat for r and j formatting.
func ( *printer) ( complex128,  int,  rune) {
	// Make sure any unsupported verbs are found before the
	// calls to fmtFloat to not generate an incorrect error string.
	switch  {
	case 'v', 'b', 'g', 'G', 'f', 'F', 'e', 'E':
		.WriteByte('(')
		.fmtFloat(real(), /2, )
		// Imaginary part always has a sign.
		if math.IsNaN(imag()) {
			// By CLDR's rules, NaNs do not use patterns or signs. As this code
			// relies on AlwaysSign working for imaginary parts, we need to
			// manually handle NaNs.
			 := &.toScientific
			.setFlags()
			.updatePadding()
			.setFlags()
			 := .Symbol(number.SymNan)
			 := 0
			if ,  := .Width();  {
				 =  - utf8.RuneCountInString() - 1
			}
			if .Flags&number.PadAfterNumber == 0 {
				for ;  > 0; -- {
					.WriteRune(.PadRune)
				}
			}
			.WriteString(.Symbol(number.SymPlusSign))
			.WriteString()
			for ;  > 0; -- {
				.WriteRune(.PadRune)
			}
			.WriteString("i)")
			return
		}
		 := .fmt.Plus
		.fmt.Plus = true
		.fmtFloat(imag(), /2, )
		.WriteString("i)") // TODO: use symbol?
		.fmt.Plus = 
	default:
		.badVerb()
	}
}

func ( *printer) ( string,  rune) {
	switch  {
	case 'v':
		if .fmt.SharpV {
			.fmt.fmt_q()
		} else {
			.fmt.fmt_s()
		}
	case 's':
		.fmt.fmt_s()
	case 'x':
		.fmt.fmt_sx(, ldigits)
	case 'X':
		.fmt.fmt_sx(, udigits)
	case 'q':
		.fmt.fmt_q()
	case 'm':
		 := .cat.Context(.tag, rawPrinter{})
		if .Execute() == catalog.ErrNotFound {
			.WriteString()
		}
	default:
		.badVerb()
	}
}

func ( *printer) ( []byte,  rune,  string) {
	switch  {
	case 'v', 'd':
		if .fmt.SharpV {
			.WriteString()
			if  == nil {
				.WriteString(nilParenString)
				return
			}
			.WriteByte('{')
			for ,  := range  {
				if  > 0 {
					.WriteString(commaSpaceString)
				}
				.fmt0x64(uint64(), true)
			}
			.WriteByte('}')
		} else {
			.WriteByte('[')
			for ,  := range  {
				if  > 0 {
					.WriteByte(' ')
				}
				.fmt.fmt_integer(uint64(), 10, unsigned, ldigits)
			}
			.WriteByte(']')
		}
	case 's':
		.fmt.fmt_s(string())
	case 'x':
		.fmt.fmt_bx(, ldigits)
	case 'X':
		.fmt.fmt_bx(, udigits)
	case 'q':
		.fmt.fmt_q(string())
	default:
		.printValue(reflect.ValueOf(), , 0)
	}
}

func ( *printer) ( reflect.Value,  rune) {
	var  uintptr
	switch .Kind() {
	case reflect.Chan, reflect.Func, reflect.Map, reflect.Ptr, reflect.Slice, reflect.UnsafePointer:
		 = .Pointer()
	default:
		.badVerb()
		return
	}

	switch  {
	case 'v':
		if .fmt.SharpV {
			.WriteByte('(')
			.WriteString(.Type().String())
			.WriteString(")(")
			if  == 0 {
				.WriteString(nilString)
			} else {
				.fmt0x64(uint64(), true)
			}
			.WriteByte(')')
		} else {
			if  == 0 {
				.fmt.padString(nilAngleString)
			} else {
				.fmt0x64(uint64(), !.fmt.Sharp)
			}
		}
	case 'p':
		.fmt0x64(uint64(), !.fmt.Sharp)
	case 'b', 'o', 'd', 'x', 'X':
		if  == 'd' {
			.fmt.Sharp = true // Print as standard go. TODO: does this make sense?
		}
		.fmtInteger(uint64(), unsigned, )
	default:
		.badVerb()
	}
}

func ( *printer) ( interface{},  rune) {
	if  := recover();  != nil {
		// If it's a nil pointer, just say "<nil>". The likeliest causes are a
		// Stringer that fails to guard against nil or a nil pointer for a
		// value receiver, and in either case, "<nil>" is a nice result.
		if  := reflect.ValueOf(); .Kind() == reflect.Ptr && .IsNil() {
			.WriteString(nilAngleString)
			return
		}
		// Otherwise print a concise panic message. Most of the time the panic
		// value will print itself nicely.
		if .panicking {
			// Nested panics; the recursion in printArg cannot succeed.
			panic()
		}

		 := .fmt.Parser
		// For this output we want default behavior.
		.fmt.ClearFlags()

		.WriteString(percentBangString)
		.WriteRune()
		.WriteString(panicString)
		.panicking = true
		.printArg(, 'v')
		.panicking = false
		.WriteByte(')')

		.fmt.Parser = 
	}
}

func ( *printer) ( rune) ( bool) {
	if .erroring {
		return
	}
	// Is it a Formatter?
	if ,  := .arg.(format.Formatter);  {
		 = true
		defer .catchPanic(.arg, )
		.Format(, )
		return
	}
	if ,  := .arg.(fmt.Formatter);  {
		 = true
		defer .catchPanic(.arg, )
		.Format(, )
		return
	}

	// If we're doing Go syntax and the argument knows how to supply it, take care of it now.
	if .fmt.SharpV {
		if ,  := .arg.(fmt.GoStringer);  {
			 = true
			defer .catchPanic(.arg, )
			// Print the result of GoString unadorned.
			.fmt.fmt_s(.GoString())
			return
		}
	} else {
		// If a string is acceptable according to the format, see if
		// the value satisfies one of the string-valued interfaces.
		// Println etc. set verb to %v, which is "stringable".
		switch  {
		case 'v', 's', 'x', 'X', 'q':
			// Is it an error or Stringer?
			// The duplication in the bodies is necessary:
			// setting handled and deferring catchPanic
			// must happen before calling the method.
			switch v := .arg.(type) {
			case error:
				 = true
				defer .catchPanic(.arg, )
				.fmtString(.Error(), )
				return

			case fmt.Stringer:
				 = true
				defer .catchPanic(.arg, )
				.fmtString(.String(), )
				return
			}
		}
	}
	return false
}

func ( *printer) ( interface{},  rune) {
	.arg = 
	.value = reflect.Value{}

	if  == nil {
		switch  {
		case 'T', 'v':
			.fmt.padString(nilAngleString)
		default:
			.badVerb()
		}
		return
	}

	// Special processing considerations.
	// %T (the value's type) and %p (its address) are special; we always do them first.
	switch  {
	case 'T':
		.fmt.fmt_s(reflect.TypeOf().String())
		return
	case 'p':
		.fmtPointer(reflect.ValueOf(), 'p')
		return
	}

	// Some types can be done without reflection.
	switch f := .(type) {
	case bool:
		.fmtBool(, )
	case float32:
		.fmtFloat(float64(), 32, )
	case float64:
		.fmtFloat(, 64, )
	case complex64:
		.fmtComplex(complex128(), 64, )
	case complex128:
		.fmtComplex(, 128, )
	case int:
		.fmtInteger(uint64(), signed, )
	case int8:
		.fmtInteger(uint64(), signed, )
	case int16:
		.fmtInteger(uint64(), signed, )
	case int32:
		.fmtInteger(uint64(), signed, )
	case int64:
		.fmtInteger(uint64(), signed, )
	case uint:
		.fmtInteger(uint64(), unsigned, )
	case uint8:
		.fmtInteger(uint64(), unsigned, )
	case uint16:
		.fmtInteger(uint64(), unsigned, )
	case uint32:
		.fmtInteger(uint64(), unsigned, )
	case uint64:
		.fmtInteger(, unsigned, )
	case uintptr:
		.fmtInteger(uint64(), unsigned, )
	case string:
		.fmtString(, )
	case []byte:
		.fmtBytes(, , "[]byte")
	case reflect.Value:
		// Handle extractable values with special methods
		// since printValue does not handle them at depth 0.
		if .IsValid() && .CanInterface() {
			.arg = .Interface()
			if .handleMethods() {
				return
			}
		}
		.printValue(, , 0)
	default:
		// If the type is not simple, it might have methods.
		if !.handleMethods() {
			// Need to use reflection, since the type had no
			// interface methods that could be used for formatting.
			.printValue(reflect.ValueOf(), , 0)
		}
	}
}

// printValue is similar to printArg but starts with a reflect value, not an interface{} value.
// It does not handle 'p' and 'T' verbs because these should have been already handled by printArg.
func ( *printer) ( reflect.Value,  rune,  int) {
	// Handle values with special methods if not already handled by printArg (depth == 0).
	if  > 0 && .IsValid() && .CanInterface() {
		.arg = .Interface()
		if .handleMethods() {
			return
		}
	}
	.arg = nil
	.value = 

	switch  := ; .Kind() {
	case reflect.Invalid:
		if  == 0 {
			.WriteString(invReflectString)
		} else {
			switch  {
			case 'v':
				.WriteString(nilAngleString)
			default:
				.badVerb()
			}
		}
	case reflect.Bool:
		.fmtBool(.Bool(), )
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		.fmtInteger(uint64(.Int()), signed, )
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
		.fmtInteger(.Uint(), unsigned, )
	case reflect.Float32:
		.fmtFloat(.Float(), 32, )
	case reflect.Float64:
		.fmtFloat(.Float(), 64, )
	case reflect.Complex64:
		.fmtComplex(.Complex(), 64, )
	case reflect.Complex128:
		.fmtComplex(.Complex(), 128, )
	case reflect.String:
		.fmtString(.String(), )
	case reflect.Map:
		if .fmt.SharpV {
			.WriteString(.Type().String())
			if .IsNil() {
				.WriteString(nilParenString)
				return
			}
			.WriteByte('{')
		} else {
			.WriteString(mapString)
		}
		 := .MapKeys()
		for ,  := range  {
			if  > 0 {
				if .fmt.SharpV {
					.WriteString(commaSpaceString)
				} else {
					.WriteByte(' ')
				}
			}
			.(, , +1)
			.WriteByte(':')
			.(.MapIndex(), , +1)
		}
		if .fmt.SharpV {
			.WriteByte('}')
		} else {
			.WriteByte(']')
		}
	case reflect.Struct:
		if .fmt.SharpV {
			.WriteString(.Type().String())
		}
		.WriteByte('{')
		for  := 0;  < .NumField(); ++ {
			if  > 0 {
				if .fmt.SharpV {
					.WriteString(commaSpaceString)
				} else {
					.WriteByte(' ')
				}
			}
			if .fmt.PlusV || .fmt.SharpV {
				if  := .Type().Field().Name;  != "" {
					.WriteString()
					.WriteByte(':')
				}
			}
			.(getField(, ), , +1)
		}
		.WriteByte('}')
	case reflect.Interface:
		 := .Elem()
		if !.IsValid() {
			if .fmt.SharpV {
				.WriteString(.Type().String())
				.WriteString(nilParenString)
			} else {
				.WriteString(nilAngleString)
			}
		} else {
			.(, , +1)
		}
	case reflect.Array, reflect.Slice:
		switch  {
		case 's', 'q', 'x', 'X':
			// Handle byte and uint8 slices and arrays special for the above verbs.
			 := .Type()
			if .Elem().Kind() == reflect.Uint8 {
				var  []byte
				if .Kind() == reflect.Slice {
					 = .Bytes()
				} else if .CanAddr() {
					 = .Slice(0, .Len()).Bytes()
				} else {
					// We have an array, but we cannot Slice() a non-addressable array,
					// so we build a slice by hand. This is a rare case but it would be nice
					// if reflection could help a little more.
					 = make([]byte, .Len())
					for  := range  {
						[] = byte(.Index().Uint())
					}
				}
				.fmtBytes(, , .String())
				return
			}
		}
		if .fmt.SharpV {
			.WriteString(.Type().String())
			if .Kind() == reflect.Slice && .IsNil() {
				.WriteString(nilParenString)
				return
			}
			.WriteByte('{')
			for  := 0;  < .Len(); ++ {
				if  > 0 {
					.WriteString(commaSpaceString)
				}
				.(.Index(), , +1)
			}
			.WriteByte('}')
		} else {
			.WriteByte('[')
			for  := 0;  < .Len(); ++ {
				if  > 0 {
					.WriteByte(' ')
				}
				.(.Index(), , +1)
			}
			.WriteByte(']')
		}
	case reflect.Ptr:
		// pointer to array or slice or struct?  ok at top level
		// but not embedded (avoid loops)
		if  == 0 && .Pointer() != 0 {
			switch  := .Elem(); .Kind() {
			case reflect.Array, reflect.Slice, reflect.Struct, reflect.Map:
				.WriteByte('&')
				.(, , +1)
				return
			}
		}
		fallthrough
	case reflect.Chan, reflect.Func, reflect.UnsafePointer:
		.fmtPointer(, )
	default:
		.unknownType()
	}
}

func ( *printer) ( rune) {
	.WriteString(percentBangString)
	.WriteRune()
	.WriteString(badIndexString)
}

func ( *printer) ( rune) {
	.WriteString(percentBangString)
	.WriteRune()
	.WriteString(missingString)
}

func ( *printer) ( string) {
	for .fmt.Parser.SetFormat(); .fmt.Scan(); {
		switch .fmt.Status {
		case format.StatusText:
			.WriteString(.fmt.Text())
		case format.StatusSubstitution:
			.printArg(.Arg(.fmt.ArgNum), .fmt.Verb)
		case format.StatusBadWidthSubstitution:
			.WriteString(badWidthString)
			.printArg(.Arg(.fmt.ArgNum), .fmt.Verb)
		case format.StatusBadPrecSubstitution:
			.WriteString(badPrecString)
			.printArg(.Arg(.fmt.ArgNum), .fmt.Verb)
		case format.StatusNoVerb:
			.WriteString(noVerbString)
		case format.StatusBadArgNum:
			.badArgNum(.fmt.Verb)
		case format.StatusMissingArg:
			.missingArg(.fmt.Verb)
		default:
			panic("unreachable")
		}
	}

	// Check for extra arguments, but only if there was at least one ordered
	// argument. Note that this behavior is necessarily different from fmt:
	// different variants of messages may opt to drop some or all of the
	// arguments.
	if !.fmt.Reordered && .fmt.ArgNum < len(.fmt.Args) && .fmt.ArgNum != 0 {
		.fmt.ClearFlags()
		.WriteString(extraString)
		for ,  := range .fmt.Args[.fmt.ArgNum:] {
			if  > 0 {
				.WriteString(commaSpaceString)
			}
			if  == nil {
				.WriteString(nilAngleString)
			} else {
				.WriteString(reflect.TypeOf().String())
				.WriteString("=")
				.printArg(, 'v')
			}
		}
		.WriteByte(')')
	}
}

func ( *printer) ( []interface{}) {
	 := false
	for ,  := range  {
		 :=  != nil && reflect.TypeOf().Kind() == reflect.String
		// Add a space between two non-string arguments.
		if  > 0 && ! && ! {
			.WriteByte(' ')
		}
		.printArg(, 'v')
		 = 
	}
}

// doPrintln is like doPrint but always adds a space between arguments
// and a newline after the last argument.
func ( *printer) ( []interface{}) {
	for ,  := range  {
		if  > 0 {
			.WriteByte(' ')
		}
		.printArg(, 'v')
	}
	.WriteByte('\n')
}