encoder.go 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  1. package apiquery
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "reflect"
  6. "strconv"
  7. "strings"
  8. "sync"
  9. "time"
  10. "github.com/sst/opencode-sdk-go/internal/param"
  11. )
  12. var encoders sync.Map // map[reflect.Type]encoderFunc
  13. type encoder struct {
  14. dateFormat string
  15. root bool
  16. settings QuerySettings
  17. }
  18. type encoderFunc func(key string, value reflect.Value) []Pair
  19. type encoderField struct {
  20. tag parsedStructTag
  21. fn encoderFunc
  22. idx []int
  23. }
  24. type encoderEntry struct {
  25. reflect.Type
  26. dateFormat string
  27. root bool
  28. settings QuerySettings
  29. }
  30. type Pair struct {
  31. key string
  32. value string
  33. }
  34. func (e *encoder) typeEncoder(t reflect.Type) encoderFunc {
  35. entry := encoderEntry{
  36. Type: t,
  37. dateFormat: e.dateFormat,
  38. root: e.root,
  39. settings: e.settings,
  40. }
  41. if fi, ok := encoders.Load(entry); ok {
  42. return fi.(encoderFunc)
  43. }
  44. // To deal with recursive types, populate the map with an
  45. // indirect func before we build it. This type waits on the
  46. // real func (f) to be ready and then calls it. This indirect
  47. // func is only used for recursive types.
  48. var (
  49. wg sync.WaitGroup
  50. f encoderFunc
  51. )
  52. wg.Add(1)
  53. fi, loaded := encoders.LoadOrStore(entry, encoderFunc(func(key string, v reflect.Value) []Pair {
  54. wg.Wait()
  55. return f(key, v)
  56. }))
  57. if loaded {
  58. return fi.(encoderFunc)
  59. }
  60. // Compute the real encoder and replace the indirect func with it.
  61. f = e.newTypeEncoder(t)
  62. wg.Done()
  63. encoders.Store(entry, f)
  64. return f
  65. }
  66. func marshalerEncoder(key string, value reflect.Value) []Pair {
  67. s, _ := value.Interface().(json.Marshaler).MarshalJSON()
  68. return []Pair{{key, string(s)}}
  69. }
  70. func (e *encoder) newTypeEncoder(t reflect.Type) encoderFunc {
  71. if t.ConvertibleTo(reflect.TypeOf(time.Time{})) {
  72. return e.newTimeTypeEncoder(t)
  73. }
  74. if !e.root && t.Implements(reflect.TypeOf((*json.Marshaler)(nil)).Elem()) {
  75. return marshalerEncoder
  76. }
  77. e.root = false
  78. switch t.Kind() {
  79. case reflect.Pointer:
  80. encoder := e.typeEncoder(t.Elem())
  81. return func(key string, value reflect.Value) (pairs []Pair) {
  82. if !value.IsValid() || value.IsNil() {
  83. return
  84. }
  85. pairs = encoder(key, value.Elem())
  86. return
  87. }
  88. case reflect.Struct:
  89. return e.newStructTypeEncoder(t)
  90. case reflect.Array:
  91. fallthrough
  92. case reflect.Slice:
  93. return e.newArrayTypeEncoder(t)
  94. case reflect.Map:
  95. return e.newMapEncoder(t)
  96. case reflect.Interface:
  97. return e.newInterfaceEncoder()
  98. default:
  99. return e.newPrimitiveTypeEncoder(t)
  100. }
  101. }
  102. func (e *encoder) newStructTypeEncoder(t reflect.Type) encoderFunc {
  103. if t.Implements(reflect.TypeOf((*param.FieldLike)(nil)).Elem()) {
  104. return e.newFieldTypeEncoder(t)
  105. }
  106. encoderFields := []encoderField{}
  107. // This helper allows us to recursively collect field encoders into a flat
  108. // array. The parameter `index` keeps track of the access patterns necessary
  109. // to get to some field.
  110. var collectEncoderFields func(r reflect.Type, index []int)
  111. collectEncoderFields = func(r reflect.Type, index []int) {
  112. for i := 0; i < r.NumField(); i++ {
  113. idx := append(index, i)
  114. field := t.FieldByIndex(idx)
  115. if !field.IsExported() {
  116. continue
  117. }
  118. // If this is an embedded struct, traverse one level deeper to extract
  119. // the field and get their encoders as well.
  120. if field.Anonymous {
  121. collectEncoderFields(field.Type, idx)
  122. continue
  123. }
  124. // If query tag is not present, then we skip, which is intentionally
  125. // different behavior from the stdlib.
  126. ptag, ok := parseQueryStructTag(field)
  127. if !ok {
  128. continue
  129. }
  130. if ptag.name == "-" && !ptag.inline {
  131. continue
  132. }
  133. dateFormat, ok := parseFormatStructTag(field)
  134. oldFormat := e.dateFormat
  135. if ok {
  136. switch dateFormat {
  137. case "date-time":
  138. e.dateFormat = time.RFC3339
  139. case "date":
  140. e.dateFormat = "2006-01-02"
  141. }
  142. }
  143. encoderFields = append(encoderFields, encoderField{ptag, e.typeEncoder(field.Type), idx})
  144. e.dateFormat = oldFormat
  145. }
  146. }
  147. collectEncoderFields(t, []int{})
  148. return func(key string, value reflect.Value) (pairs []Pair) {
  149. for _, ef := range encoderFields {
  150. var subkey string = e.renderKeyPath(key, ef.tag.name)
  151. if ef.tag.inline {
  152. subkey = key
  153. }
  154. field := value.FieldByIndex(ef.idx)
  155. pairs = append(pairs, ef.fn(subkey, field)...)
  156. }
  157. return
  158. }
  159. }
  160. func (e *encoder) newMapEncoder(t reflect.Type) encoderFunc {
  161. keyEncoder := e.typeEncoder(t.Key())
  162. elementEncoder := e.typeEncoder(t.Elem())
  163. return func(key string, value reflect.Value) (pairs []Pair) {
  164. iter := value.MapRange()
  165. for iter.Next() {
  166. encodedKey := keyEncoder("", iter.Key())
  167. if len(encodedKey) != 1 {
  168. panic("Unexpected number of parts for encoded map key. Are you using a non-primitive for this map?")
  169. }
  170. subkey := encodedKey[0].value
  171. keyPath := e.renderKeyPath(key, subkey)
  172. pairs = append(pairs, elementEncoder(keyPath, iter.Value())...)
  173. }
  174. return
  175. }
  176. }
  177. func (e *encoder) renderKeyPath(key string, subkey string) string {
  178. if len(key) == 0 {
  179. return subkey
  180. }
  181. if e.settings.NestedFormat == NestedQueryFormatDots {
  182. return fmt.Sprintf("%s.%s", key, subkey)
  183. }
  184. return fmt.Sprintf("%s[%s]", key, subkey)
  185. }
  186. func (e *encoder) newArrayTypeEncoder(t reflect.Type) encoderFunc {
  187. switch e.settings.ArrayFormat {
  188. case ArrayQueryFormatComma:
  189. innerEncoder := e.typeEncoder(t.Elem())
  190. return func(key string, v reflect.Value) []Pair {
  191. elements := []string{}
  192. for i := 0; i < v.Len(); i++ {
  193. for _, pair := range innerEncoder("", v.Index(i)) {
  194. elements = append(elements, pair.value)
  195. }
  196. }
  197. if len(elements) == 0 {
  198. return []Pair{}
  199. }
  200. return []Pair{{key, strings.Join(elements, ",")}}
  201. }
  202. case ArrayQueryFormatRepeat:
  203. innerEncoder := e.typeEncoder(t.Elem())
  204. return func(key string, value reflect.Value) (pairs []Pair) {
  205. for i := 0; i < value.Len(); i++ {
  206. pairs = append(pairs, innerEncoder(key, value.Index(i))...)
  207. }
  208. return pairs
  209. }
  210. case ArrayQueryFormatIndices:
  211. panic("The array indices format is not supported yet")
  212. case ArrayQueryFormatBrackets:
  213. innerEncoder := e.typeEncoder(t.Elem())
  214. return func(key string, value reflect.Value) []Pair {
  215. pairs := []Pair{}
  216. for i := 0; i < value.Len(); i++ {
  217. pairs = append(pairs, innerEncoder(key+"[]", value.Index(i))...)
  218. }
  219. return pairs
  220. }
  221. default:
  222. panic(fmt.Sprintf("Unknown ArrayFormat value: %d", e.settings.ArrayFormat))
  223. }
  224. }
  225. func (e *encoder) newPrimitiveTypeEncoder(t reflect.Type) encoderFunc {
  226. switch t.Kind() {
  227. case reflect.Pointer:
  228. inner := t.Elem()
  229. innerEncoder := e.newPrimitiveTypeEncoder(inner)
  230. return func(key string, v reflect.Value) []Pair {
  231. if !v.IsValid() || v.IsNil() {
  232. return nil
  233. }
  234. return innerEncoder(key, v.Elem())
  235. }
  236. case reflect.String:
  237. return func(key string, v reflect.Value) []Pair {
  238. return []Pair{{key, v.String()}}
  239. }
  240. case reflect.Bool:
  241. return func(key string, v reflect.Value) []Pair {
  242. if v.Bool() {
  243. return []Pair{{key, "true"}}
  244. }
  245. return []Pair{{key, "false"}}
  246. }
  247. case reflect.Int, reflect.Int16, reflect.Int32, reflect.Int64:
  248. return func(key string, v reflect.Value) []Pair {
  249. return []Pair{{key, strconv.FormatInt(v.Int(), 10)}}
  250. }
  251. case reflect.Uint, reflect.Uint16, reflect.Uint32, reflect.Uint64:
  252. return func(key string, v reflect.Value) []Pair {
  253. return []Pair{{key, strconv.FormatUint(v.Uint(), 10)}}
  254. }
  255. case reflect.Float32, reflect.Float64:
  256. return func(key string, v reflect.Value) []Pair {
  257. return []Pair{{key, strconv.FormatFloat(v.Float(), 'f', -1, 64)}}
  258. }
  259. case reflect.Complex64, reflect.Complex128:
  260. bitSize := 64
  261. if t.Kind() == reflect.Complex128 {
  262. bitSize = 128
  263. }
  264. return func(key string, v reflect.Value) []Pair {
  265. return []Pair{{key, strconv.FormatComplex(v.Complex(), 'f', -1, bitSize)}}
  266. }
  267. default:
  268. return func(key string, v reflect.Value) []Pair {
  269. return nil
  270. }
  271. }
  272. }
  273. func (e *encoder) newFieldTypeEncoder(t reflect.Type) encoderFunc {
  274. f, _ := t.FieldByName("Value")
  275. enc := e.typeEncoder(f.Type)
  276. return func(key string, value reflect.Value) []Pair {
  277. present := value.FieldByName("Present")
  278. if !present.Bool() {
  279. return nil
  280. }
  281. null := value.FieldByName("Null")
  282. if null.Bool() {
  283. // TODO: Error?
  284. return nil
  285. }
  286. raw := value.FieldByName("Raw")
  287. if !raw.IsNil() {
  288. return e.typeEncoder(raw.Type())(key, raw)
  289. }
  290. return enc(key, value.FieldByName("Value"))
  291. }
  292. }
  293. func (e *encoder) newTimeTypeEncoder(t reflect.Type) encoderFunc {
  294. format := e.dateFormat
  295. return func(key string, value reflect.Value) []Pair {
  296. return []Pair{{
  297. key,
  298. value.Convert(reflect.TypeOf(time.Time{})).Interface().(time.Time).Format(format),
  299. }}
  300. }
  301. }
  302. func (e encoder) newInterfaceEncoder() encoderFunc {
  303. return func(key string, value reflect.Value) []Pair {
  304. value = value.Elem()
  305. if !value.IsValid() {
  306. return nil
  307. }
  308. return e.typeEncoder(value.Type())(key, value)
  309. }
  310. }