From 98b0a4ef3d06fd4bc46809f0cb0f19f1bd205802 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C5=99emysl=20Eric=20Janouch?= Date: Thu, 15 Sep 2022 03:15:52 +0200 Subject: [PATCH] xP: further optimize JSON marshalling --- xC-gen-proto-go.awk | 47 ++++++++++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 20 deletions(-) diff --git a/xC-gen-proto-go.awk b/xC-gen-proto-go.awk index a2244b5..48371eb 100644 --- a/xC-gen-proto-go.awk +++ b/xC-gen-proto-go.awk @@ -15,6 +15,9 @@ function define_sint(size, shortname, gotype) { gotype = "int" size define_internal(shortname, gotype) + CodegenAppendJSON[shortname] = \ + "\tb = strconv.AppendInt(b, int64(%s), 10)\n" + if (size == 8) { CodegenSerialize[shortname] = "\tdata = append(data, uint8(%s))\n" CodegenDeserialize[shortname] = \ @@ -42,6 +45,9 @@ function define_uint(size, shortname, gotype) { gotype = "uint" size define_internal(shortname, gotype) + CodegenAppendJSON[shortname] = \ + "\tb = strconv.AppendUint(b, uint64(%s), 10)\n" + # Both byte and uint8 luckily marshal as base64-encoded JSON strings. if (size == 8) { CodegenSerialize[shortname] = "\tdata = append(data, %s)\n" @@ -76,6 +82,8 @@ function codegen_begin() { define_uint("64") define_internal("bool", "bool") + CodegenAppendJSON["bool"] = \ + "\tb = strconv.AppendBool(b, %s)\n" CodegenSerialize["bool"] = \ "\tif %s {\n" \ "\t\tdata = append(data, 1)\n" \ @@ -254,24 +262,32 @@ function codegen_enum(name, cg, gotype, fields) { delete cg[i] } +function codegen_marshal(type, f, marshal) { + if (CodegenAppendJSON[type]) + return sprintf(CodegenAppendJSON[type], f) + + if (CodegenIsMarshaler[type]) + marshal = f ".MarshalJSON()" + else + marshal = "json.Marshal(" f ")" + + return \ + "\tif j, err := " marshal "; err != nil {\n" \ + "\t\treturn nil, err\n" \ + "\t} else {\n" \ + "\t\tb = append(b, j...)\n" \ + "\t}\n" +} + function codegen_struct_field_marshal(d, cg, camel, f, marshal) { camel = snaketocamel(d["name"]) f = "s." camel # Complex types are json.Marshalers, there's no need to json.Marshal(&f). if (!d["isarray"]) { - if (CodegenIsMarshaler[d["type"]]) - marshal = f ".MarshalJSON()" - else - marshal = "json.Marshal(" f ")" - append(cg, "marshal", "\tb = append(b, `,\"" decapitalize(camel) "\":`...)\n" \ - "\tif j, err := " marshal "; err != nil {\n" \ - "\t\treturn nil, err\n" \ - "\t} else {\n" \ - "\t\tb = append(b, j...)\n" \ - "\t}\n") + codegen_marshal(d["type"], f)) return } @@ -283,22 +299,13 @@ function codegen_struct_field_marshal(d, cg, camel, f, marshal) { return } - if (CodegenIsMarshaler[d["type"]]) - marshal = f "[i].MarshalJSON()" - else - marshal = "json.Marshal(" f "[i])" - append(cg, "marshal", "\tb = append(b, `,\"" decapitalize(camel) "\":[`...)\n" \ "\tfor i := 0; i < len(" f "); i++ {\n" \ "\t\tif i > 0 {\n" \ "\t\t\tb = append(b, ',')\n" \ "\t\t}\n" \ - "\t\tif j, err := " marshal "; err != nil {\n" \ - "\t\t\treturn nil, err\n" \ - "\t\t} else {\n" \ - "\t\t\tb = append(b, j...)\n" \ - "\t\t}\n" \ + indent(codegen_marshal(d["type"], f "[i]")) \ "\t}\n" \ "\tb = append(b, ']')\n") }