// Marshal returns the JSON encoding of v. // // Marshal traverses the value v recursively. // If an encountered value implements the Marshaler interface // and is not a nil pointer, Marshal calls its MarshalJSON method // to produce JSON. If no MarshalJSON method is present but the // value implements encoding.TextMarshaler instead, Marshal calls // its MarshalText method. // The nil pointer exception is not strictly necessary // but mimics a similar, necessary exception in the behavior of // 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. // // String values encode as JSON strings coerced to valid UTF-8, // replacing invalid bytes with the Unicode replacement rune. // The angle brackets "<" and ">" are escaped to "\u003c" and "\u003e" // to keep some browsers from misinterpreting JSON output as HTML. // Ampersand "&" is also escaped to "\u0026" for the same reason. // // 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 object. // // Struct values encode as JSON objects. Each exported struct field // becomes a member of the object unless // - the field's tag is "-", or // - the field is empty and its tag specifies the "omitempty" option. // The empty values are false, 0, any // nil pointer or interface value, and any array, slice, map, or string of // length zero. The object's default key string is the struct field name // but can be specified in the struct field's tag value. The "json" key in // the struct field's tag value is the key name, followed by an optional comma // and options. Examples: // // // Field is ignored by this package. // Field int `json:"-"` // // // 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"` // // 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, dollar signs, percent signs, hyphens, // underscores and slashes. // // Anonymous 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 be string; the map keys are used as JSON object // keys, subject to the UTF-8 coercion described for string values above. // // Pointer values encode as the value pointed to. // A nil pointer encodes as the null JSON object. // // Interface values encode as the value contained in the interface. // A nil interface value encodes as the null JSON object. // // 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 infinite recursion. // func Marshal(v interface{ … } // MarshalIndent is like Marshal but applies Indent to format the output. func MarshalIndent(v interface{ … } // HTMLEscape appends to dst the JSON-encoded src with <, >, &, U+2028 and U+2029 // characters inside string literals changed to \u003c, \u003e, \u0026, \u2028, \u2029 // so that the JSON will be safe to embed inside HTML <script> tags. // For historical reasons, web browsers don't honor standard HTML // escaping within <script> tags, so an alternative JSON encoding must // be used. func HTMLEscape(dst *bytes.Buffer, src []byte) { … } type Marshaler … type UnsupportedTypeError … func (e *UnsupportedTypeError) Error() string { … } type UnsupportedValueError … func (e *UnsupportedValueError) Error() string { … } type InvalidUTF8Error … func (e *InvalidUTF8Error) Error() string { … } type MarshalerError … func (e *MarshalerError) Error() string { … } var hex … type encodeState … var encodeStatePool … func newEncodeState() *encodeState { … } func (e *encodeState) marshal(v interface{ … } func (e *encodeState) error(err error) { … } func isEmptyValue(v reflect.Value) bool { … } func (e *encodeState) reflectValue(v reflect.Value) { … } type encoderFunc … var encoderCache … func valueEncoder(v reflect.Value) encoderFunc { … } func typeEncoder(t reflect.Type) encoderFunc { … } var marshalerType … var textMarshalerType … // newTypeEncoder constructs an encoderFunc for a type. // The returned encoder only checks CanAddr when allowAddr is true. func newTypeEncoder(t reflect.Type, allowAddr bool) encoderFunc { … } func invalidValueEncoder(e *encodeState, v reflect.Value, quoted bool) { … } func marshalerEncoder(e *encodeState, v reflect.Value, quoted bool) { … } func addrMarshalerEncoder(e *encodeState, v reflect.Value, quoted bool) { … } func textMarshalerEncoder(e *encodeState, v reflect.Value, quoted bool) { … } func addrTextMarshalerEncoder(e *encodeState, v reflect.Value, quoted bool) { … } func boolEncoder(e *encodeState, v reflect.Value, quoted bool) { … } func intEncoder(e *encodeState, v reflect.Value, quoted bool) { … } func uintEncoder(e *encodeState, v reflect.Value, quoted bool) { … } type floatEncoder … func (bits floatEncoder) encode(e *encodeState, v reflect.Value, quoted bool) { … } var float32Encoder … var float64Encoder … func stringEncoder(e *encodeState, v reflect.Value, quoted bool) { … } func interfaceEncoder(e *encodeState, v reflect.Value, quoted bool) { … } func unsupportedTypeEncoder(e *encodeState, v reflect.Value, quoted bool) { … } type structEncoder … func (se *structEncoder) encode(e *encodeState, v reflect.Value, quoted bool) { … } func newStructEncoder(t reflect.Type) encoderFunc { … } type mapEncoder … func (me *mapEncoder) encode(e *encodeState, v reflect.Value, _ bool) { … } func newMapEncoder(t reflect.Type) encoderFunc { … } func encodeByteSlice(e *encodeState, v reflect.Value, _ bool) { … } type sliceEncoder … func (se *sliceEncoder) encode(e *encodeState, v reflect.Value, _ bool) { … } func newSliceEncoder(t reflect.Type) encoderFunc { … } type arrayEncoder … func (ae *arrayEncoder) encode(e *encodeState, v reflect.Value, _ bool) { … } func newArrayEncoder(t reflect.Type) encoderFunc { … } type ptrEncoder … func (pe *ptrEncoder) encode(e *encodeState, v reflect.Value, quoted bool) { … } func newPtrEncoder(t reflect.Type) encoderFunc { … } type condAddrEncoder … func (ce *condAddrEncoder) encode(e *encodeState, v reflect.Value, quoted bool) { … } // newCondAddrEncoder returns an encoder that checks whether its value // CanAddr and delegates to canAddrEnc if so, else to elseEnc. func newCondAddrEncoder(canAddrEnc, elseEnc encoderFunc) encoderFunc { … } func isValidTag(s string) bool { … } func fieldByIndex(v reflect.Value, index []int) reflect.Value { … } func typeByIndex(t reflect.Type, index []int) reflect.Type { … } type stringValues … func (sv stringValues) Len() int { … } func (sv stringValues) Swap(i, j int) { … } func (sv stringValues) Less(i, j int) bool { … } func (sv stringValues) get(i int) string { … } // NOTE: keep in sync with stringBytes below. func (e *encodeState) string(s string) int { … } // NOTE: keep in sync with string above. func (e *encodeState) stringBytes(s []byte) int { … } type field … func fillField(f field) field { … } type byName … func (x byName) Len() int { … } func (x byName) Swap(i, j int) { … } func (x byName) Less(i, j int) bool { … } type byIndex … func (x byIndex) Len() int { … } func (x byIndex) Swap(i, j int) { … } func (x byIndex) Less(i, j int) bool { … } // typeFields returns a list of fields that JSON should recognize for the given type. // The algorithm is breadth-first search over the set of structs to include - the top struct // and then any reachable anonymous structs. func typeFields(t reflect.Type) []field { … } // dominantField looks through the fields, all of which are known to // have the same name, to find the single field that dominates the // others using Go's embedding rules, modified by the presence of // JSON tags. If there are multiple top-level fields, the boolean // will be false: This condition is an error in Go and we skip all // the fields. func dominantField(fields []field) (field, bool) { … } var fieldCache … // cachedTypeFields is like typeFields but uses a cache to avoid repeated work. func cachedTypeFields(t reflect.Type) []field { … }