Source file src/encoding/json/v2_encode.go
1 // Copyright 2010 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 //go:build goexperiment.jsonv2 6 7 // Package json implements encoding and decoding of JSON as defined in 8 // RFC 7159. The mapping between JSON and Go values is described 9 // in the documentation for the Marshal and Unmarshal functions. 10 // 11 // See [JSON and Go] for an introduction to this package. 12 // 13 // # Security Considerations 14 // 15 // See the "Security Considerations" section in [encoding/json/v2]. 16 // 17 // For historical reasons, the default behavior of v1 [encoding/json] 18 // unfortunately operates with less secure defaults. 19 // New usages of JSON in Go are encouraged to use [encoding/json/v2] instead. 20 // 21 // [JSON and Go]: https://go.dev/blog/json 22 package json 23 24 import ( 25 "reflect" 26 "strconv" 27 28 jsonv2 "encoding/json/v2" 29 ) 30 31 // Marshal returns the JSON encoding of v. 32 // 33 // Marshal traverses the value v recursively. 34 // 35 // The input value is encoded as JSON according the following rules: 36 // 37 // - If the value type implements [jsonv2.MarshalerTo], 38 // then the MarshalJSONTo method is called to encode the value. 39 // If the method returns [errors.ErrUnsupported], 40 // then the input is encoded according to subsequent rules. 41 // 42 // - If the value type implements [Marshaler], 43 // then the MarshalJSON method is called to encode the value. 44 // 45 // - If the value type implements [encoding.TextAppender], 46 // then the AppendText method is called to encode the value and 47 // subsequently encode its result as a JSON string. 48 // 49 // - If the value type implements [encoding.TextMarshaler], 50 // then the MarshalText method is called to encode the value and 51 // subsequently encode its result as a JSON string. 52 // 53 // Otherwise, Marshal uses the following type-dependent default encodings: 54 // 55 // Boolean values encode as JSON booleans. 56 // 57 // Floating point, integer, and [Number] values encode as JSON numbers. 58 // NaN and +/-Inf values will return an [UnsupportedValueError]. 59 // 60 // String values encode as JSON strings coerced to valid UTF-8, 61 // replacing invalid bytes with the Unicode replacement rune. 62 // So that the JSON will be safe to embed inside HTML <script> tags, 63 // the string is encoded using [HTMLEscape], 64 // which replaces "<", ">", "&", U+2028, and U+2029 are escaped 65 // to "\u003c","\u003e", "\u0026", "\u2028", and "\u2029". 66 // This replacement can be disabled when using an [Encoder], 67 // by calling [Encoder.SetEscapeHTML](false). 68 // 69 // Array and slice values encode as JSON arrays, except that 70 // []byte encodes as a base64-encoded string, and a nil slice 71 // encodes as the null JSON value. 72 // 73 // Struct values encode as JSON objects. 74 // Each exported struct field becomes a member of the object, using the 75 // field name as the object key, unless the field is omitted for one of the 76 // reasons given below. 77 // 78 // The encoding of each struct field can be customized by the format string 79 // stored under the "json" key in the struct field's tag. 80 // The format string gives the name of the field, possibly followed by a 81 // comma-separated list of options. The name may be empty in order to 82 // specify options without overriding the default field name. 83 // 84 // The "omitempty" option specifies that the field should be omitted 85 // from the encoding if the field has an empty value, defined as 86 // false, 0, a nil pointer, a nil interface value, and any array, 87 // slice, map, or string of length zero. 88 // 89 // As a special case, if the field tag is "-", the field is always omitted. 90 // JSON names containing commas or quotes, or names identical to "" or "-", 91 // can be specified using a single-quoted string literal, where the syntax 92 // is identical to the Go grammar for a double-quoted string literal, 93 // but instead uses single quotes as the delimiters. 94 // 95 // Examples of struct field tags and their meanings: 96 // 97 // // Field appears in JSON as key "myName". 98 // Field int `json:"myName"` 99 // 100 // // Field appears in JSON as key "myName" and 101 // // the field is omitted from the object if its value is empty, 102 // // as defined above. 103 // Field int `json:"myName,omitempty"` 104 // 105 // // Field appears in JSON as key "Field" (the default), but 106 // // the field is skipped if empty. 107 // // Note the leading comma. 108 // Field int `json:",omitempty"` 109 // 110 // // Field is ignored by this package. 111 // Field int `json:"-"` 112 // 113 // // Field appears in JSON as key "-". 114 // Field int `json:"'-'"` 115 // 116 // The "omitzero" option specifies that the field should be omitted 117 // from the encoding if the field has a zero value, according to rules: 118 // 119 // 1) If the field type has an "IsZero() bool" method, that will be used to 120 // determine whether the value is zero. 121 // 122 // 2) Otherwise, the value is zero if it is the zero value for its type. 123 // 124 // If both "omitempty" and "omitzero" are specified, the field will be omitted 125 // if the value is either empty or zero (or both). 126 // 127 // The "string" option signals that a field is stored as JSON inside a 128 // JSON-encoded string. It applies only to fields of string, floating point, 129 // integer, or boolean types. This extra level of encoding is sometimes used 130 // when communicating with JavaScript programs: 131 // 132 // Int64String int64 `json:",string"` 133 // 134 // The key name will be used if it's a non-empty string consisting of 135 // only Unicode letters, digits, and ASCII punctuation except quotation 136 // marks, backslash, and comma. 137 // 138 // Embedded struct fields are usually marshaled as if their inner exported fields 139 // were fields in the outer struct, subject to the usual Go visibility rules amended 140 // as described in the next paragraph. 141 // An anonymous struct field with a name given in its JSON tag is treated as 142 // having that name, rather than being anonymous. 143 // An anonymous struct field of interface type is treated the same as having 144 // that type as its name, rather than being anonymous. 145 // 146 // The Go visibility rules for struct fields are amended for JSON when 147 // deciding which field to marshal or unmarshal. If there are 148 // multiple fields at the same level, and that level is the least 149 // nested (and would therefore be the nesting level selected by the 150 // usual Go rules), the following extra rules apply: 151 // 152 // 1) Of those fields, if any are JSON-tagged, only tagged fields are considered, 153 // even if there are multiple untagged fields that would otherwise conflict. 154 // 155 // 2) If there is exactly one field (tagged or not according to the first rule), that is selected. 156 // 157 // 3) Otherwise there are multiple fields, and all are ignored; no error occurs. 158 // 159 // Handling of anonymous struct fields is new in Go 1.1. 160 // Prior to Go 1.1, anonymous struct fields were ignored. To force ignoring of 161 // an anonymous struct field in both current and earlier versions, give the field 162 // a JSON tag of "-". 163 // 164 // Map values encode as JSON objects. The map's key type must either be a 165 // string, an integer type, or implement [encoding.TextMarshaler]. The map keys 166 // are sorted and used as JSON object keys by applying the following rules, 167 // subject to the UTF-8 coercion described for string values above: 168 // - keys of any string type are used directly 169 // - keys that implement [encoding.TextMarshaler] are marshaled 170 // - integer keys are converted to strings 171 // 172 // Pointer values encode as the value pointed to. 173 // A nil pointer encodes as the null JSON value. 174 // 175 // Interface values encode as the value contained in the interface. 176 // A nil interface value encodes as the null JSON value. 177 // 178 // Channel, complex, and function values cannot be encoded in JSON. 179 // Attempting to encode such a value causes Marshal to return 180 // an [UnsupportedTypeError]. 181 // 182 // JSON cannot represent cyclic data structures and Marshal does not 183 // handle them. Passing cyclic structures to Marshal will result in 184 // an error. 185 func Marshal(v any) ([]byte, error) { 186 return jsonv2.Marshal(v, DefaultOptionsV1()) 187 } 188 189 // MarshalIndent is like [Marshal] but applies [Indent] to format the output. 190 // Each JSON element in the output will begin on a new line beginning with prefix 191 // followed by one or more copies of indent according to the indentation nesting. 192 func MarshalIndent(v any, prefix, indent string) ([]byte, error) { 193 b, err := Marshal(v) 194 if err != nil { 195 return nil, err 196 } 197 b, err = appendIndent(nil, b, prefix, indent) 198 if err != nil { 199 return nil, err 200 } 201 return b, nil 202 } 203 204 // Marshaler is the interface implemented by types that 205 // can marshal themselves into valid JSON. 206 type Marshaler = jsonv2.Marshaler 207 208 // An UnsupportedTypeError is returned by [Marshal] when attempting 209 // to encode an unsupported value type. 210 type UnsupportedTypeError struct { 211 Type reflect.Type 212 } 213 214 func (e *UnsupportedTypeError) Error() string { 215 return "json: unsupported type: " + e.Type.String() 216 } 217 218 // An UnsupportedValueError is returned by [Marshal] when attempting 219 // to encode an unsupported value. 220 type UnsupportedValueError struct { 221 Value reflect.Value 222 Str string 223 } 224 225 func (e *UnsupportedValueError) Error() string { 226 return "json: unsupported value: " + e.Str 227 } 228 229 // Before Go 1.2, an InvalidUTF8Error was returned by [Marshal] when 230 // attempting to encode a string value with invalid UTF-8 sequences. 231 // As of Go 1.2, [Marshal] instead coerces the string to valid UTF-8 by 232 // replacing invalid bytes with the Unicode replacement rune U+FFFD. 233 // 234 // Deprecated: No longer used; kept for compatibility. 235 type InvalidUTF8Error struct { 236 S string // the whole string value that caused the error 237 } 238 239 func (e *InvalidUTF8Error) Error() string { 240 return "json: invalid UTF-8 in string: " + strconv.Quote(e.S) 241 } 242 243 // A MarshalerError represents an error from calling a 244 // [Marshaler.MarshalJSON] or [encoding.TextMarshaler.MarshalText] method. 245 type MarshalerError struct { 246 Type reflect.Type 247 Err error 248 sourceFunc string 249 } 250 251 func (e *MarshalerError) Error() string { 252 srcFunc := e.sourceFunc 253 if srcFunc == "" { 254 srcFunc = "MarshalJSON" 255 } 256 return "json: error calling " + srcFunc + 257 " for type " + e.Type.String() + 258 ": " + e.Err.Error() 259 } 260 261 // Unwrap returns the underlying error. 262 func (e *MarshalerError) Unwrap() error { return e.Err } 263