// 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 implements encoding and decoding of JSON as defined in // RFC 7159. The mapping between JSON and Go values is described // in the documentation for the Marshal and Unmarshal functions. // // See "JSON and Go" for an introduction to this package: // https://golang.org/doc/articles/json_and_go.html
package json import ( jsonv2 ) // Marshal returns the JSON encoding of v. // // Marshal traverses the value v recursively. // If an encountered value implements [Marshaler] // and is not a nil pointer, Marshal calls [Marshaler.MarshalJSON] // to produce JSON. If no [Marshaler.MarshalJSON] method is present but the // value implements [encoding.TextMarshaler] instead, Marshal calls // [encoding.TextMarshaler.MarshalText] and encodes the result as a JSON string. // The nil pointer exception is not strictly necessary // but mimics a similar, necessary exception in the behavior of // [Unmarshaler.UnmarshalJSON]. // // Otherwise, Marshal uses the following type-dependent default encodings: // // Boolean values encode as JSON booleans. // // Floating point, integer, and [Number] values encode as JSON numbers. // NaN and +/-Inf values will return an [UnsupportedValueError]. // // String values encode as JSON strings coerced to valid UTF-8, // replacing invalid bytes with the Unicode replacement rune. // So that the JSON will be safe to embed inside HTML <script> tags, // the string is encoded using [HTMLEscape], // which replaces "<", ">", "&", U+2028, and U+2029 are escaped // to "\u003c","\u003e", "\u0026", "\u2028", and "\u2029". // This replacement can be disabled when using an [Encoder], // by calling [Encoder.SetEscapeHTML](false). // // Array and slice values encode as JSON arrays, except that // []byte encodes as a base64-encoded string, and a nil slice // encodes as the null JSON value. // // Struct values encode as JSON objects. // Each exported struct field becomes a member of the object, using the // field name as the object key, unless the field is omitted for one of the // reasons given below. // // The encoding of each struct field can be customized by the format string // stored under the "json" key in the struct field's tag. // The format string gives the name of the field, possibly followed by a // comma-separated list of options. The name may be empty in order to // specify options without overriding the default field name. // // The "omitempty" option specifies that the field should be omitted // from the encoding if the field has an empty value, defined as // false, 0, a nil pointer, a nil interface value, and any array, // slice, map, or string of length zero. // // As a special case, if the field tag is "-", the field is always omitted. // Note that a field with name "-" can still be generated using the tag "-,". // // Examples of struct field tags and their meanings: // // // Field appears in JSON as key "myName". // Field int `json:"myName"` // // // Field appears in JSON as key "myName" and // // the field is omitted from the object if its value is empty, // // as defined above. // Field int `json:"myName,omitempty"` // // // Field appears in JSON as key "Field" (the default), but // // the field is skipped if empty. // // Note the leading comma. // Field int `json:",omitempty"` // // // Field is ignored by this package. // Field int `json:"-"` // // // Field appears in JSON as key "-". // Field int `json:"-,"` // // The "omitzero" option specifies that the field should be omitted // from the encoding if the field has a zero value, according to rules: // // 1) If the field type has an "IsZero() bool" method, that will be used to // determine whether the value is zero. // // 2) Otherwise, the value is zero if it is the zero value for its type. // // If both "omitempty" and "omitzero" are specified, the field will be omitted // if the value is either empty or zero (or both). // // The "string" option signals that a field is stored as JSON inside a // JSON-encoded string. It applies only to fields of string, floating point, // integer, or boolean types. This extra level of encoding is sometimes used // when communicating with JavaScript programs: // // Int64String int64 `json:",string"` // // The key name will be used if it's a non-empty string consisting of // only Unicode letters, digits, and ASCII punctuation except quotation // marks, backslash, and comma. // // Embedded struct fields are usually marshaled as if their inner exported fields // were fields in the outer struct, subject to the usual Go visibility rules amended // as described in the next paragraph. // An anonymous struct field with a name given in its JSON tag is treated as // having that name, rather than being anonymous. // An anonymous struct field of interface type is treated the same as having // that type as its name, rather than being anonymous. // // The Go visibility rules for struct fields are amended for JSON when // deciding which field to marshal or unmarshal. If there are // multiple fields at the same level, and that level is the least // nested (and would therefore be the nesting level selected by the // usual Go rules), the following extra rules apply: // // 1) Of those fields, if any are JSON-tagged, only tagged fields are considered, // even if there are multiple untagged fields that would otherwise conflict. // // 2) If there is exactly one field (tagged or not according to the first rule), that is selected. // // 3) Otherwise there are multiple fields, and all are ignored; no error occurs. // // Handling of anonymous struct fields is new in Go 1.1. // Prior to Go 1.1, anonymous struct fields were ignored. To force ignoring of // an anonymous struct field in both current and earlier versions, give the field // a JSON tag of "-". // // Map values encode as JSON objects. The map's key type must either be a // string, an integer type, or implement [encoding.TextMarshaler]. The map keys // are sorted and used as JSON object keys by applying the following rules, // subject to the UTF-8 coercion described for string values above: // - keys of any string type are used directly // - keys that implement [encoding.TextMarshaler] are marshaled // - integer keys are converted to strings // // Pointer values encode as the value pointed to. // A nil pointer encodes as the null JSON value. // // Interface values encode as the value contained in the interface. // A nil interface value encodes as the null JSON value. // // Channel, complex, and function values cannot be encoded in JSON. // Attempting to encode such a value causes Marshal to return // an [UnsupportedTypeError]. // // JSON cannot represent cyclic data structures and Marshal does not // handle them. Passing cyclic structures to Marshal will result in // an error. func ( any) ([]byte, error) { return jsonv2.Marshal(, DefaultOptionsV1()) } // MarshalIndent is like [Marshal] but applies [Indent] to format the output. // Each JSON element in the output will begin on a new line beginning with prefix // followed by one or more copies of indent according to the indentation nesting. func ( any, , string) ([]byte, error) { , := Marshal() if != nil { return nil, } , = appendIndent(nil, , , ) if != nil { return nil, } return , nil } // Marshaler is the interface implemented by types that // can marshal themselves into valid JSON. type Marshaler = jsonv2.Marshaler // An UnsupportedTypeError is returned by [Marshal] when attempting // to encode an unsupported value type. type UnsupportedTypeError struct { Type reflect.Type } func ( *UnsupportedTypeError) () string { return "json: unsupported type: " + .Type.String() } // An UnsupportedValueError is returned by [Marshal] when attempting // to encode an unsupported value. type UnsupportedValueError struct { Value reflect.Value Str string } func ( *UnsupportedValueError) () string { return "json: unsupported value: " + .Str } // Before Go 1.2, an InvalidUTF8Error was returned by [Marshal] when // attempting to encode a string value with invalid UTF-8 sequences. // As of Go 1.2, [Marshal] instead coerces the string to valid UTF-8 by // replacing invalid bytes with the Unicode replacement rune U+FFFD. // // Deprecated: No longer used; kept for compatibility. type InvalidUTF8Error struct { S string // the whole string value that caused the error } func ( *InvalidUTF8Error) () string { return "json: invalid UTF-8 in string: " + strconv.Quote(.S) } // A MarshalerError represents an error from calling a // [Marshaler.MarshalJSON] or [encoding.TextMarshaler.MarshalText] method. type MarshalerError struct { Type reflect.Type Err error sourceFunc string } func ( *MarshalerError) () string { := .sourceFunc if == "" { = "MarshalJSON" } return "json: error calling " + + " for type " + .Type.String() + ": " + .Err.Error() } // Unwrap returns the underlying error. func ( *MarshalerError) () error { return .Err }