This commit is contained in:
2026-04-01 10:53:51 +03:00
parent 281af49d27
commit c1890216c5
16 changed files with 722 additions and 62 deletions
+25 -2
View File
@@ -15,6 +15,8 @@ func GenerateGo(messages []parser.Message, pkgName string) ([]byte, error) {
func GenerateGoSchema(schema parser.Schema, pkgName string) ([]byte, error) {
messages := schema.Messages
var b strings.Builder
needsLengthGuards := schemaNeedsLengthGuards(messages)
needsQuantGuards := schemaNeedsQuantRangeGuards(messages)
b.WriteString("// Code generated by arpack. DO NOT EDIT.\n\n")
fmt.Fprintf(&b, "package %s\n\n", pkgName)
@@ -27,6 +29,23 @@ func GenerateGoSchema(schema parser.Schema, pkgName string) ([]byte, error) {
}
b.WriteString(")\n\n")
if needsLengthGuards {
b.WriteString("func arpackEnsureUint16Length(length int, context string) uint16 {\n")
b.WriteString("\tif length > 65535 {\n")
b.WriteString("\t\tpanic(\"arpack: \" + context + \" exceeds uint16 limit\")\n")
b.WriteString("\t}\n")
b.WriteString("\treturn uint16(length)\n")
b.WriteString("}\n\n")
}
if needsQuantGuards {
b.WriteString("func arpackEnsureQuantizedRange(value float64, min float64, max float64, context string) {\n")
b.WriteString("\tif value != value || value < min || value > max {\n")
b.WriteString("\t\tpanic(\"arpack: quantized value out of range for \" + context)\n")
b.WriteString("\t}\n")
b.WriteString("}\n\n")
}
for _, msg := range messages {
if err := writeGoMessage(&b, msg); err != nil {
return nil, fmt.Errorf("message %s: %w", msg.Name, err)
@@ -120,7 +139,8 @@ func writeGoMarshalField(b *strings.Builder, recv string, f parser.Field, indent
}
fmt.Fprintf(b, "%s}\n", indent)
case parser.KindSlice:
fmt.Fprintf(b, "%sbuf = binary.LittleEndian.AppendUint16(buf, uint16(len(%s)))\n", indent, access)
fmt.Fprintf(b, "%sbuf = binary.LittleEndian.AppendUint16(buf, arpackEnsureUint16Length(len(%s), %q))\n",
indent, access, lengthContext(f))
fmt.Fprintf(b, "%sfor _i%s := range %s {\n", indent, f.Name, access)
elemField := parser.Field{
Name: f.Name + "[_i" + f.Name + "]",
@@ -169,7 +189,8 @@ func writeGoMarshalPrimitive(b *strings.Builder, access string, f parser.Field,
case parser.KindUint64:
fmt.Fprintf(b, "%sbuf = binary.LittleEndian.AppendUint64(buf, %s)\n", indent, valueExpr)
case parser.KindString:
fmt.Fprintf(b, "%sbuf = binary.LittleEndian.AppendUint16(buf, uint16(len(%s)))\n", indent, valueExpr)
fmt.Fprintf(b, "%sbuf = binary.LittleEndian.AppendUint16(buf, arpackEnsureUint16Length(len(%s), %q))\n",
indent, valueExpr, lengthContext(f))
fmt.Fprintf(b, "%sbuf = append(buf, %s...)\n", indent, valueExpr)
}
return nil
@@ -179,6 +200,8 @@ func writeGoMarshalQuant(b *strings.Builder, access string, f parser.Field, inde
q := f.Quant
varName := "_q" + sanitizeVarName(access)
valueExpr := goMarshalValueExpr(access, f)
fmt.Fprintf(b, "%sarpackEnsureQuantizedRange(float64(%s), %g, %g, %q)\n",
indent, valueExpr, q.Min, q.Max, quantContext(f))
if q.Bits == 8 {
fmt.Fprintf(b, "%s%s := uint8((%s - (%g)) / (%g - (%g)) * %g)\n",
indent, varName, valueExpr, q.Min, q.Max, q.Min, q.MaxUint())