reflect.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413
  1. package core
  2. import (
  3. "fmt"
  4. "bytes"
  5. "errors"
  6. "strings"
  7. "strconv"
  8. "reflect"
  9. "math/big"
  10. "encoding/json"
  11. "kumachan/lang/source"
  12. "kumachan/lang/typsys"
  13. )
  14. type ReflectType struct { type_ typsys.CertainType }
  15. func MakeReflectType(t typsys.CertainType) ReflectType {
  16. var u_ = convertToReflectiveType(t.Type)
  17. var u = typsys.CertainType { Type: u_ }
  18. return ReflectType { u }
  19. }
  20. func (rt ReflectType) CertainType() typsys.CertainType {
  21. return rt.type_
  22. }
  23. func (rt ReflectType) Type() typsys.Type {
  24. return rt.CertainType().Type
  25. }
  26. var genericType = typsys.Type(typsys.RefType {
  27. Def: source.MakeRef("", T_GenericType),
  28. Args: [] typsys.Type {},
  29. })
  30. func convertToReflectiveType(t typsys.Type) typsys.Type {
  31. return typsys.Transform(t, func(t typsys.Type) (typsys.Type, bool) {
  32. switch t.(type) {
  33. case typsys.InferringType:
  34. return genericType, true
  35. case typsys.ParameterType:
  36. return genericType, true
  37. case typsys.RefType:
  38. return nil, false
  39. default:
  40. panic("impossible branch")
  41. }
  42. })
  43. }
  44. type ReflectValue struct {
  45. type_ ReflectType
  46. value Object
  47. }
  48. func AssumeValidReflectValue(t ReflectType, v Object) ReflectValue {
  49. return ReflectValue {
  50. type_: t,
  51. value: v,
  52. }
  53. }
  54. func (rv ReflectValue) Type() ReflectType {
  55. return rv.type_
  56. }
  57. func (rv ReflectValue) Value() Object {
  58. return rv.value
  59. }
  60. type ReflectObservable struct {
  61. innerType ReflectType
  62. observableValue Observable
  63. }
  64. func (rv ReflectValue) CastToReflectObservable() ReflectObservable {
  65. if T, ok := rv.Type().Type().(typsys.RefType); ok {
  66. if T.Def.Namespace == "" && T.Def.ItemName == T_Observable {
  67. if len(T.Args) == 1 {
  68. var t_ = T.Args[0]
  69. var t = typsys.CertainType { Type: t_ }
  70. return ReflectObservable {
  71. innerType: MakeReflectType(t),
  72. observableValue: GetObservable(rv.Value()),
  73. }
  74. }}}
  75. panic("cannot cast non-observable object to ReflectObservable")
  76. }
  77. func (ro ReflectObservable) InnerType() ReflectType {
  78. return ro.innerType
  79. }
  80. func (ro ReflectObservable) ObservableValue() Observable {
  81. return ro.observableValue
  82. }
  83. type SerializationContext interface {
  84. LookupType(rt ReflectType) (*typsys.TypeDef, source.Ref, ([] typsys.Type), bool)
  85. }
  86. func Marshal(rv ReflectValue, ctx SerializationContext) ([] byte, error) {
  87. var m = jsonMarshaler { rv, ctx }
  88. var b, err = m.MarshalJSON()
  89. if err != nil {
  90. if cause := errors.Unwrap(err); cause != nil {
  91. return nil, cause
  92. }
  93. return nil, err
  94. }
  95. return b, nil
  96. }
  97. func Unmarshal(b ([] byte), rt ReflectType, ctx SerializationContext) (Object, error) {
  98. var m = jsonUnmarshaler { rt, nil, ctx }
  99. var err = json.Unmarshal(b, &m)
  100. if err != nil { return nil, err }
  101. return m.value, nil
  102. }
  103. type jsonMarshaler struct {
  104. value ReflectValue
  105. context SerializationContext
  106. }
  107. func (m jsonMarshaler) MarshalJSON() ([] byte, error) {
  108. var rt = m.value.Type()
  109. var obj = m.value.Value()
  110. var ctx = m.context
  111. var def, ref, args, exists = ctx.LookupType(rt)
  112. if !(exists) { panic("something went wrong") }
  113. switch content := def.Content.(type) {
  114. case typsys.NativeContent:
  115. if ref.Namespace == "" {
  116. switch ref.ItemName {
  117. case T_Null:
  118. return ([] byte)("null"), nil
  119. case T_Bool:
  120. return json.Marshal(GetBool(obj))
  121. case T_Int:
  122. return json.Marshal(GetIntAsRawBigInt(obj))
  123. case T_Float:
  124. // NOTE: error on NaN, +Inf, -Inf
  125. return json.Marshal(GetFloat(obj))
  126. case T_String:
  127. return json.Marshal(GetString(obj))
  128. case T_Bytes:
  129. return json.Marshal(GetBytes(obj))
  130. case T_List:
  131. var l = GetList(obj)
  132. var slice = make([] jsonMarshaler, l.Length())
  133. var item_rt = firstArgType(args)
  134. l.ForEachWithIndex(func(i int, item_v Object) {
  135. var item_rv = AssumeValidReflectValue(item_rt, item_v)
  136. slice[i] = jsonMarshaler { item_rv, ctx }
  137. })
  138. return json.Marshal(slice)
  139. }
  140. }
  141. case typsys.Record:
  142. var r = (*obj).(Record)
  143. var buf jsonMarshalerRecordStructBuilder
  144. for i, field := range content.FieldList {
  145. var field_name = field.Name
  146. var field_rt = inflateFieldType(field, def, args)
  147. var field_v = r.Objects[i]
  148. var field_rv = AssumeValidReflectValue(field_rt, field_v)
  149. buf.append(field_name, field_rv, ctx)
  150. }
  151. var struct_ = buf.collect()
  152. return json.Marshal(struct_)
  153. case typsys.Union:
  154. if ref == source.MakeRef("", T_Maybe) {
  155. var inner_rt = firstArgType(args)
  156. var inner_v, ok = UnwrapMaybe(obj)
  157. if ok {
  158. var inner_rv = AssumeValidReflectValue(inner_rt, inner_v)
  159. var inner = jsonMarshaler { inner_rv, ctx }
  160. return json.Marshal(inner)
  161. } else {
  162. return ([] byte)("null"), nil
  163. }
  164. } else {
  165. var u = (*obj).(Union)
  166. var index = u.Index
  167. var inner_v = u.Object
  168. var field = content.FieldList[index]
  169. var inner_rt = inflateFieldType(field, def, args)
  170. var inner_rv = AssumeValidReflectValue(inner_rt, inner_v)
  171. var struct_ = jsonMarshalerUnionStruct {
  172. Index: u.Index,
  173. Object: jsonMarshaler { inner_rv, ctx },
  174. }
  175. return json.Marshal(struct_)
  176. }
  177. case typsys.Enum:
  178. var e = (*obj).(Enum)
  179. var index = int(e)
  180. var field = content.FieldList[index]
  181. var field_name = field.Name
  182. return json.Marshal(field_name)
  183. }
  184. return nil, errors.New(fmt.Sprintf(
  185. "serialization is unavailable for type %s",
  186. typsys.Describe(rt.Type()),
  187. ))
  188. }
  189. type jsonUnmarshaler struct {
  190. type_ ReflectType
  191. value Object
  192. context SerializationContext
  193. }
  194. func (m *jsonUnmarshaler) UnmarshalJSON(b ([] byte)) error {
  195. if len(b) == 0 {
  196. return errors.New("empty content")
  197. }
  198. var rt = m.type_
  199. var v = &(m.value)
  200. var ctx = m.context
  201. var def, ref, args, exists = ctx.LookupType(rt)
  202. if !(exists) { panic("something went wrong") }
  203. switch content := def.Content.(type) {
  204. case typsys.NativeContent:
  205. if ref.Namespace == "" {
  206. switch ref.ItemName {
  207. case T_Null:
  208. return nil
  209. case T_Bool:
  210. return jsonUnmarshalPrimitive[bool] (b,v)
  211. case T_Int:
  212. return jsonUnmarshalPrimitive[*big.Int] (b,v)
  213. case T_Float:
  214. return jsonUnmarshalPrimitive[float64] (b,v)
  215. case T_String:
  216. return jsonUnmarshalPrimitive[string] (b,v)
  217. case T_Bytes:
  218. return jsonUnmarshalPrimitive[[]byte] (b,v)
  219. case T_List:
  220. var segments ([] json.RawMessage)
  221. var err = json.Unmarshal(b, &segments)
  222. if err != nil { return err }
  223. var nodes = make([] ListNode, len(segments))
  224. var item_rt = firstArgType(args)
  225. for i, s := range segments {
  226. var item = &(nodes[i].Value)
  227. var err = jsonUnmarshalObject(s, item, item_rt, ctx)
  228. if err != nil { return err }
  229. }
  230. var l = NodesToList(nodes)
  231. *v = Obj(l)
  232. return nil
  233. }
  234. }
  235. case typsys.Record:
  236. var buf jsonUnmarshalerRecordStructBuilder
  237. for _, field := range content.FieldList {
  238. var field_name = field.Name
  239. var field_rt = inflateFieldType(field, def, args)
  240. buf.append(field_name, field_rt, ctx)
  241. }
  242. var objects, err = buf.collect(b)
  243. if err != nil { return err }
  244. *v = Obj(Record { objects })
  245. return nil
  246. case typsys.Union:
  247. if ref == source.MakeRef("", T_Maybe) {
  248. if bytes.Equal(b, ([] byte)("null")) {
  249. *v = Nothing()
  250. return nil
  251. } else {
  252. var inner_rt = firstArgType(args)
  253. var inner = new(Object)
  254. var err = jsonUnmarshalObject(b, inner, inner_rt, ctx)
  255. if err != nil { return err }
  256. *v = Just(*inner)
  257. return nil
  258. }
  259. } else {
  260. var struct_ = jsonUnmarshalerUnionStruct { Index: -1 }
  261. var err1 = json.Unmarshal(b, &struct_)
  262. if err1 != nil { return err1 }
  263. var index = struct_.Index
  264. var inner_raw = struct_.Object
  265. var L = len(content.FieldList)
  266. if !(0 <= index && index < L) { return errors.New("invalid union") }
  267. var field = content.FieldList[index]
  268. var inner_rt = inflateFieldType(field, def, args)
  269. var inner = new(Object)
  270. var err2 = jsonUnmarshalObject(inner_raw, inner, inner_rt, ctx)
  271. if err2 != nil { return err2 }
  272. *v = Obj(Union { Index: index, Object: *inner })
  273. return nil
  274. }
  275. case typsys.Enum:
  276. var field_name string
  277. var err = json.Unmarshal(b, &field_name)
  278. if err != nil { return err }
  279. var index = content.FieldIndexMap[field_name]
  280. var e = Enum(index)
  281. *v = Obj(e)
  282. return nil
  283. }
  284. return errors.New(fmt.Sprintf(
  285. "serialization is unavailable for type %s",
  286. typsys.Describe(rt.Type()),
  287. ))
  288. }
  289. func firstArgType(args ([] typsys.Type)) ReflectType {
  290. var t_ = args[0]
  291. var t = typsys.CertainType { Type: t_ }
  292. var rt = MakeReflectType(t)
  293. return rt
  294. }
  295. func inflateFieldType(field typsys.Field, def *typsys.TypeDef, args ([] typsys.Type)) ReflectType {
  296. var t_ = typsys.Inflate(field.Type, def.Parameters, args)
  297. var t = typsys.CertainType { Type: t_ }
  298. var rt = MakeReflectType(t)
  299. return rt
  300. }
  301. func jsonUnmarshalPrimitive[T any] (b ([] byte), v *Object) error {
  302. var temp T
  303. var err = json.Unmarshal(b, &temp)
  304. if err != nil { return err }
  305. *v = ToObject(temp)
  306. return nil
  307. }
  308. func jsonUnmarshalObject(b ([] byte), v *Object, rt ReflectType, ctx SerializationContext) error {
  309. var m = jsonUnmarshaler { rt, nil, ctx }
  310. var err = json.Unmarshal(b, &m)
  311. if err != nil { return err }
  312. *v = m.value
  313. return nil
  314. }
  315. type jsonMarshalerUnionStruct struct {
  316. Index int
  317. Object jsonMarshaler
  318. }
  319. type jsonMarshalerRecordStructBuilder struct {
  320. fields [] reflect.StructField
  321. values [] jsonMarshaler
  322. }
  323. func (buf *jsonMarshalerRecordStructBuilder) append(name string, rv ReflectValue, ctx SerializationContext) {
  324. var field = jsonStructField (
  325. name, reflect.TypeOf(jsonMarshaler {}), len(buf.fields),
  326. )
  327. var value = jsonMarshaler {
  328. rv, ctx,
  329. }
  330. buf.fields = append(buf.fields, field)
  331. buf.values = append(buf.values, value)
  332. }
  333. func (buf *jsonMarshalerRecordStructBuilder) collect() interface{} {
  334. var ptr_rv = reflect.New(reflect.StructOf(buf.fields))
  335. var rv = ptr_rv.Elem()
  336. for i := 0; i < len(buf.fields); i += 1 {
  337. var m = buf.values[i]
  338. rv.Field(i).Set(reflect.ValueOf(m))
  339. }
  340. var v = rv.Interface()
  341. return v
  342. }
  343. type jsonUnmarshalerUnionStruct struct {
  344. Index int
  345. Object json.RawMessage
  346. }
  347. type jsonUnmarshalerRecordStructBuilder struct {
  348. fields [] reflect.StructField
  349. values [] jsonUnmarshaler
  350. }
  351. func (buf *jsonUnmarshalerRecordStructBuilder) append(name string, type_ ReflectType, ctx SerializationContext) {
  352. var field = jsonStructField (
  353. name, reflect.TypeOf(jsonUnmarshaler {}), len(buf.fields),
  354. )
  355. var value = jsonUnmarshaler {
  356. type_, nil, ctx,
  357. }
  358. buf.fields = append(buf.fields, field)
  359. buf.values = append(buf.values, value)
  360. }
  361. func (buf *jsonUnmarshalerRecordStructBuilder) collect(b ([] byte)) ([] Object, error) {
  362. var L = len(buf.fields)
  363. var ptr_rv = reflect.New(reflect.StructOf(buf.fields))
  364. var rv = ptr_rv.Elem()
  365. for i := 0; i < L; i += 1 {
  366. var m = buf.values[i]
  367. rv.Field(i).Set(reflect.ValueOf(m))
  368. }
  369. var ptr = ptr_rv.Interface()
  370. var err = json.Unmarshal(b, ptr)
  371. if err != nil { return nil, err }
  372. var objects = make([] Object, L)
  373. for i := 0; i < L; i += 1 {
  374. var field_value = rv.Field(i).Interface().(jsonUnmarshaler).value
  375. if field_value == nil {
  376. var m = buf.values[i]
  377. var field_type = m.type_
  378. var _, ref, _, exists = m.context.LookupType(field_type)
  379. if !(exists) { panic("something went wrong") }
  380. if ref.Namespace == "" {
  381. switch ref.ItemName {
  382. case T_Null:
  383. goto OK
  384. case T_Maybe:
  385. field_value = Nothing()
  386. goto OK
  387. }
  388. }
  389. var tag = rv.Type().Field(i).Tag
  390. var field_name = strings.TrimPrefix(string(tag), "json:")
  391. return nil, errors.New("missing field: " + field_name)
  392. }
  393. OK:
  394. objects[i] = field_value
  395. }
  396. return objects, nil
  397. }
  398. func jsonStructField(name string, type_ reflect.Type, n int) reflect.StructField {
  399. return reflect.StructField {
  400. Name: fmt.Sprintf("Export_%d", n),
  401. Tag: reflect.StructTag(fmt.Sprintf("json:%s", strconv.Quote(name))),
  402. Type: type_,
  403. }
  404. }