func()

in jsonpb/encode.go [420:511]


func (w *jsonWriter) marshalValue(fd protoreflect.FieldDescriptor, v protoreflect.Value, indent string) error {
	switch {
	case fd.IsList():
		w.write("[")
		comma := ""
		lv := v.List()
		for i := 0; i < lv.Len(); i++ {
			w.write(comma)
			if w.Indent != "" {
				w.write("\n")
				w.write(indent)
				w.write(w.Indent)
				w.write(w.Indent)
			}
			if err := w.marshalSingularValue(fd, lv.Get(i), indent+w.Indent); err != nil {
				return err
			}
			comma = ","
		}
		if w.Indent != "" {
			w.write("\n")
			w.write(indent)
			w.write(w.Indent)
		}
		w.write("]")
		return nil
	case fd.IsMap():
		kfd := fd.MapKey()
		vfd := fd.MapValue()
		mv := v.Map()

		// Collect a sorted list of all map keys and values.
		type entry struct{ key, val protoreflect.Value }
		var entries []entry
		mv.Range(func(k protoreflect.MapKey, v protoreflect.Value) bool {
			entries = append(entries, entry{k.Value(), v})
			return true
		})
		sort.Slice(entries, func(i, j int) bool {
			switch kfd.Kind() {
			case protoreflect.BoolKind:
				return !entries[i].key.Bool() && entries[j].key.Bool()
			case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind, protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind:
				return entries[i].key.Int() < entries[j].key.Int()
			case protoreflect.Uint32Kind, protoreflect.Fixed32Kind, protoreflect.Uint64Kind, protoreflect.Fixed64Kind:
				return entries[i].key.Uint() < entries[j].key.Uint()
			case protoreflect.StringKind:
				return entries[i].key.String() < entries[j].key.String()
			default:
				panic("invalid kind")
			}
		})

		w.write(`{`)
		comma := ""
		for _, entry := range entries {
			w.write(comma)
			if w.Indent != "" {
				w.write("\n")
				w.write(indent)
				w.write(w.Indent)
				w.write(w.Indent)
			}

			s := fmt.Sprint(entry.key.Interface())
			b, err := json.Marshal(s)
			if err != nil {
				return err
			}
			w.write(string(b))

			w.write(`:`)
			if w.Indent != "" {
				w.write(` `)
			}

			if err := w.marshalSingularValue(vfd, entry.val, indent+w.Indent); err != nil {
				return err
			}
			comma = ","
		}
		if w.Indent != "" {
			w.write("\n")
			w.write(indent)
			w.write(w.Indent)
		}
		w.write(`}`)
		return nil
	default:
		return w.marshalSingularValue(fd, v, indent)
	}
}