// Copyright 2010 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.

//go:build goexperiment.jsonv2

package json

import (
	
	
	

	
	
	
)

// export exposes internal functionality of the "jsontext" package.
var export = jsontext.Internal.Export(&internal.AllowInternalUse)

// Valid reports whether data is a valid JSON encoding.
func ( []byte) bool {
	return checkValid() == nil
}

func checkValid( []byte) error {
	 := export.GetBufferedDecoder()
	defer export.PutBufferedDecoder()
	 := export.Decoder()
	.Struct.Flags.Set(jsonflags.AllowDuplicateNames | jsonflags.AllowInvalidUTF8 | 1)
	if ,  := .ReadValue();  != nil {
		return transformSyntacticError()
	}
	if  := .CheckEOF();  != nil {
		return transformSyntacticError()
	}
	return nil
}

// A SyntaxError is a description of a JSON syntax error.
// [Unmarshal] will return a SyntaxError if the JSON can't be parsed.
type SyntaxError struct {
	msg    string // description of error
	Offset int64  // error occurred after reading Offset bytes
}

func ( *SyntaxError) () string { return .msg }

var errUnexpectedEnd = errors.New("unexpected end of JSON input")

func transformSyntacticError( error) error {
	switch ,  := .(*jsontext.SyntacticError); {
	case  != nil:
		if .Err == io.ErrUnexpectedEOF {
			.Err = errUnexpectedEnd
		}
		 := .Err.Error()
		if  := strings.Index(, " (expecting");  >= 0 && !strings.Contains(, " in literal") {
			 = [:]
		}
		return &SyntaxError{Offset: .ByteOffset, msg: syntaxErrorReplacer.Replace()}
	case :
		return (*SyntaxError)(nil)
	case export.IsIOError():
		return errors.Unwrap() // v1 historically did not wrap IO errors
	default:
		return 
	}
}

// syntaxErrorReplacer replaces certain string literals in the v2 error
// to better match the historical string rendering of syntax errors.
// In particular, v2 uses the terminology "object name" to match RFC 8259,
// while v1 uses "object key", which is not a term found in JSON literature.
var syntaxErrorReplacer = strings.NewReplacer(
	"object name", "object key",
	"at start of value", "looking for beginning of value",
	"at start of string", "looking for beginning of object key string",
	"after object value", "after object key:value pair",
	"in number", "in numeric literal",
)