go-json/cmd/generator/main.go

828 lines
21 KiB
Go
Raw Normal View History

2020-08-15 11:41:38 +03:00
package main
import (
"bytes"
"fmt"
2020-11-12 18:25:57 +03:00
"go/format"
2020-08-15 11:41:38 +03:00
"io/ioutil"
"path/filepath"
"runtime"
"strings"
"text/template"
)
type opType struct {
2020-12-25 10:06:25 +03:00
Op string
Code string
Indent func() string
2020-12-25 10:38:18 +03:00
Escaped func() string
2020-12-25 10:06:25 +03:00
HeadToPtrHead func() string
HeadToNPtrHead func() string
HeadToAnonymousHead func() string
HeadToOmitEmptyHead func() string
HeadToStringTagHead func() string
2021-01-08 20:28:33 +03:00
HeadToOnlyHead func() string
2020-12-25 10:06:25 +03:00
PtrHeadToHead func() string
2020-12-29 18:13:45 +03:00
FieldToEnd func() string
2020-12-25 10:06:25 +03:00
FieldToOmitEmptyField func() string
FieldToStringTagField func() string
2020-08-15 11:41:38 +03:00
}
2020-12-29 21:50:19 +03:00
func (t opType) IsEscaped() bool {
return t.Op != t.Escaped()
}
func (t opType) IsHeadToPtrHead() bool {
return t.Op != t.HeadToPtrHead()
}
func (t opType) IsHeadToNPtrHead() bool {
return t.Op != t.HeadToNPtrHead()
}
func (t opType) IsHeadToAnonymousHead() bool {
return t.Op != t.HeadToAnonymousHead()
}
func (t opType) IsHeadToOmitEmptyHead() bool {
return t.Op != t.HeadToOmitEmptyHead()
}
func (t opType) IsHeadToStringTagHead() bool {
return t.Op != t.HeadToStringTagHead()
}
func (t opType) IsPtrHeadToHead() bool {
return t.Op != t.PtrHeadToHead()
}
2021-01-08 20:28:33 +03:00
func (t opType) IsHeadToOnlyHead() bool {
return t.Op != t.HeadToOnlyHead()
}
2020-12-29 21:50:19 +03:00
func (t opType) IsFieldToEnd() bool {
return t.Op != t.FieldToEnd()
}
func (t opType) IsFieldToOmitEmptyField() bool {
return t.Op != t.FieldToOmitEmptyField()
}
func (t opType) IsFieldToStringTagField() bool {
return t.Op != t.FieldToStringTagField()
}
2020-12-25 10:06:25 +03:00
func createOpType(op, code string) opType {
return opType{
Op: op,
Code: code,
Indent: func() string { return fmt.Sprintf("%sIndent", op) },
2020-12-25 10:38:18 +03:00
Escaped: func() string { return op },
2020-12-25 10:06:25 +03:00
HeadToPtrHead: func() string { return op },
HeadToNPtrHead: func() string { return op },
HeadToAnonymousHead: func() string { return op },
HeadToOmitEmptyHead: func() string { return op },
HeadToStringTagHead: func() string { return op },
2021-01-08 20:28:33 +03:00
HeadToOnlyHead: func() string { return op },
2020-12-25 10:06:25 +03:00
PtrHeadToHead: func() string { return op },
2020-12-29 18:13:45 +03:00
FieldToEnd: func() string { return op },
2020-12-25 10:06:25 +03:00
FieldToOmitEmptyField: func() string { return op },
FieldToStringTagField: func() string { return op },
}
2020-08-15 11:41:38 +03:00
}
func _main() error {
tmpl, err := template.New("").Parse(`// Code generated by cmd/generator. DO NOT EDIT!
package json
type codeType int
const (
{{- range $index, $type := .CodeTypes }}
code{{ $type }} codeType = {{ $index }}
{{- end }}
)
type opType int
const (
{{- range $index, $type := .OpTypes }}
op{{ $type.Op }} opType = {{ $index }}
{{- end }}
)
func (t opType) String() string {
2020-12-30 10:09:12 +03:00
if int(t) >= {{ .OpLen }} {
return t.toNotIndent().String() + "Indent"
}
2020-08-15 11:41:38 +03:00
switch t {
2020-12-30 10:09:12 +03:00
{{- range $type := .OpNotIndentTypes }}
2020-08-15 11:41:38 +03:00
case op{{ $type.Op }}:
return "{{ $type.Op }}"
{{- end }}
}
return ""
}
func (t opType) codeType() codeType {
2020-12-30 10:09:12 +03:00
if int(t) >= {{ .OpLen }} {
return t.toNotIndent().codeType()
}
2020-08-15 11:41:38 +03:00
switch t {
2020-12-30 10:09:12 +03:00
{{- range $type := .OpNotIndentTypes }}
2020-08-15 11:41:38 +03:00
case op{{ $type.Op }}:
return code{{ $type.Code }}
{{- end }}
}
return codeOp
}
2020-12-30 10:09:12 +03:00
func (t opType) toNotIndent() opType {
if int(t) >= {{ .OpLen }} {
return opType(int(t) - {{ .OpLen }})
2020-08-15 11:41:38 +03:00
}
return t
}
2020-12-30 10:09:12 +03:00
func (t opType) toIndent() opType {
if int(t) >= {{ .OpLen }} {
return t
}
return opType(int(t) + {{ .OpLen }})
}
2020-12-25 10:38:18 +03:00
func (t opType) toEscaped() opType {
2020-12-30 10:09:12 +03:00
if int(t) >= {{ .OpLen }} {
return opType(int(t.toNotIndent().toEscaped()) + {{ .OpLen }})
}
2020-12-25 10:38:18 +03:00
switch t {
2020-12-30 10:09:12 +03:00
{{- range $type := .OpNotIndentTypes }}
2020-12-29 21:50:19 +03:00
{{- if $type.IsEscaped }}
2020-12-25 10:38:18 +03:00
case op{{ $type.Op }}:
return op{{ call $type.Escaped }}
2020-12-29 21:50:19 +03:00
{{- end }}
2020-12-25 10:38:18 +03:00
{{- end }}
}
return t
}
2020-08-15 11:41:38 +03:00
func (t opType) headToPtrHead() opType {
2020-12-30 10:13:33 +03:00
if int(t) >= {{ .OpLen }} {
return opType(int(t.toNotIndent().headToPtrHead()) + {{ .OpLen }})
}
2020-08-15 11:41:38 +03:00
switch t {
2020-12-30 10:13:33 +03:00
{{- range $type := .OpNotIndentTypes }}
2020-12-29 21:50:19 +03:00
{{- if $type.IsHeadToPtrHead }}
2020-12-25 10:06:25 +03:00
case op{{ $type.Op }}:
return op{{ call $type.HeadToPtrHead }}
2020-12-29 21:50:19 +03:00
{{- end }}
2020-08-15 11:41:38 +03:00
{{- end }}
}
return t
}
2020-12-23 07:13:34 +03:00
func (t opType) headToNPtrHead() opType {
2020-12-30 10:13:33 +03:00
if int(t) >= {{ .OpLen }} {
return opType(int(t.toNotIndent().headToNPtrHead()) + {{ .OpLen }})
}
2020-12-23 07:13:34 +03:00
switch t {
2020-12-30 10:13:33 +03:00
{{- range $type := .OpNotIndentTypes }}
2020-12-29 21:50:19 +03:00
{{- if $type.IsHeadToNPtrHead }}
2020-12-25 10:06:25 +03:00
case op{{ $type.Op }}:
return op{{ call $type.HeadToNPtrHead }}
2020-12-29 21:50:19 +03:00
{{- end }}
2020-12-23 07:13:34 +03:00
{{- end }}
}
return t
}
2020-08-15 11:41:38 +03:00
func (t opType) headToAnonymousHead() opType {
2020-12-30 10:13:33 +03:00
if int(t) >= {{ .OpLen }} {
return opType(int(t.toNotIndent().headToAnonymousHead()) + {{ .OpLen }})
}
2020-08-15 11:41:38 +03:00
switch t {
2020-12-30 10:13:33 +03:00
{{- range $type := .OpNotIndentTypes }}
2020-12-29 21:50:19 +03:00
{{- if $type.IsHeadToAnonymousHead }}
2020-12-25 10:06:25 +03:00
case op{{ $type.Op }}:
return op{{ call $type.HeadToAnonymousHead }}
2020-12-29 21:50:19 +03:00
{{- end }}
2020-08-15 11:41:38 +03:00
{{- end }}
}
return t
}
func (t opType) headToOmitEmptyHead() opType {
2020-12-30 10:13:33 +03:00
if int(t) >= {{ .OpLen }} {
return opType(int(t.toNotIndent().headToOmitEmptyHead()) + {{ .OpLen }})
}
2020-08-15 11:41:38 +03:00
switch t {
2020-12-30 10:13:33 +03:00
{{- range $type := .OpNotIndentTypes }}
2020-12-29 21:50:19 +03:00
{{- if $type.IsHeadToOmitEmptyHead }}
2020-12-25 10:06:25 +03:00
case op{{ $type.Op }}:
return op{{ call $type.HeadToOmitEmptyHead }}
2020-12-29 21:50:19 +03:00
{{- end }}
2020-08-15 11:41:38 +03:00
{{- end }}
}
return t
}
2020-08-19 13:55:06 +03:00
func (t opType) headToStringTagHead() opType {
2020-12-30 10:13:33 +03:00
if int(t) >= {{ .OpLen }} {
return opType(int(t.toNotIndent().headToStringTagHead()) + {{ .OpLen }})
}
2020-08-19 13:55:06 +03:00
switch t {
2020-12-30 10:13:33 +03:00
{{- range $type := .OpNotIndentTypes }}
2020-12-29 21:50:19 +03:00
{{- if $type.IsHeadToStringTagHead }}
2020-12-25 10:06:25 +03:00
case op{{ $type.Op }}:
return op{{ call $type.HeadToStringTagHead }}
2020-12-29 21:50:19 +03:00
{{- end }}
2020-08-19 13:55:06 +03:00
{{- end }}
}
return t
}
2021-01-08 20:28:33 +03:00
func (t opType) headToOnlyHead() opType {
if int(t) >= {{ .OpLen }} {
return opType(int(t.toNotIndent().headToOnlyHead()) + {{ .OpLen }})
}
switch t {
{{- range $type := .OpNotIndentTypes }}
{{- if $type.IsHeadToOnlyHead }}
case op{{ $type.Op }}:
return op{{ call $type.HeadToOnlyHead }}
{{- end }}
{{- end }}
}
return t
}
2020-08-15 11:41:38 +03:00
func (t opType) ptrHeadToHead() opType {
2020-12-30 10:13:33 +03:00
if int(t) >= {{ .OpLen }} {
return opType(int(t.toNotIndent().ptrHeadToHead()) + {{ .OpLen }})
}
2020-08-15 11:41:38 +03:00
switch t {
2020-12-30 10:13:33 +03:00
{{- range $type := .OpNotIndentTypes }}
2020-12-29 21:50:19 +03:00
{{- if $type.IsPtrHeadToHead }}
2020-12-25 10:06:25 +03:00
case op{{ $type.Op }}:
return op{{ call $type.PtrHeadToHead }}
2020-12-29 21:50:19 +03:00
{{- end }}
2020-08-15 11:41:38 +03:00
{{- end }}
}
return t
}
2020-12-29 18:13:45 +03:00
func (t opType) fieldToEnd() opType {
2020-12-30 10:13:33 +03:00
if int(t) >= {{ .OpLen }} {
return opType(int(t.toNotIndent().fieldToEnd()) + {{ .OpLen }})
}
2020-12-29 18:13:45 +03:00
switch t {
2020-12-30 10:13:33 +03:00
{{- range $type := .OpNotIndentTypes }}
2020-12-29 21:50:19 +03:00
{{- if $type.IsFieldToEnd }}
2020-12-29 18:13:45 +03:00
case op{{ $type.Op }}:
return op{{ call $type.FieldToEnd }}
2020-12-29 21:50:19 +03:00
{{- end }}
2020-12-29 18:13:45 +03:00
{{- end }}
}
return t
}
2020-08-15 11:41:38 +03:00
func (t opType) fieldToOmitEmptyField() opType {
2020-12-30 10:13:33 +03:00
if int(t) >= {{ .OpLen }} {
return opType(int(t.toNotIndent().fieldToOmitEmptyField()) + {{ .OpLen }})
}
2020-08-15 11:41:38 +03:00
switch t {
2020-12-30 10:13:33 +03:00
{{- range $type := .OpNotIndentTypes }}
2020-12-29 21:50:19 +03:00
{{- if $type.IsFieldToOmitEmptyField }}
2020-12-25 10:06:25 +03:00
case op{{ $type.Op }}:
return op{{ call $type.FieldToOmitEmptyField }}
2020-12-29 21:50:19 +03:00
{{- end }}
2020-08-15 11:41:38 +03:00
{{- end }}
}
return t
}
2020-08-19 13:55:06 +03:00
func (t opType) fieldToStringTagField() opType {
2020-12-30 10:13:33 +03:00
if int(t) >= {{ .OpLen }} {
return opType(int(t.toNotIndent().fieldToStringTagField()) + {{ .OpLen }})
}
2020-08-19 13:55:06 +03:00
switch t {
2020-12-30 10:13:33 +03:00
{{- range $type := .OpNotIndentTypes }}
2020-12-29 21:50:19 +03:00
{{- if $type.IsFieldToStringTagField }}
2020-12-25 10:06:25 +03:00
case op{{ $type.Op }}:
return op{{ call $type.FieldToStringTagField }}
2020-12-29 21:50:19 +03:00
{{- end }}
2020-08-19 13:55:06 +03:00
{{- end }}
}
return t
}
2020-08-15 11:41:38 +03:00
`)
if err != nil {
return err
}
codeTypes := []string{
"Op",
"ArrayHead",
"ArrayElem",
"SliceHead",
"SliceElem",
"MapHead",
"MapKey",
"MapValue",
2020-09-16 08:51:37 +03:00
"MapEnd",
2020-08-15 11:41:38 +03:00
"StructFieldRecursive",
"StructField",
2020-12-29 18:13:45 +03:00
"StructEnd",
2020-08-15 11:41:38 +03:00
}
primitiveTypes := []string{
"int", "int8", "int16", "int32", "int64",
"uint", "uint8", "uint16", "uint32", "uint64",
2020-12-25 10:06:25 +03:00
"float32", "float64", "bool", "string", "escapedString", "bytes",
2020-11-16 15:28:33 +03:00
"array", "map", "mapLoad", "slice", "struct", "MarshalJSON", "MarshalText", "recursive",
"intString", "int8String", "int16String", "int32String", "int64String",
"uintString", "uint8String", "uint16String", "uint32String", "uint64String",
2020-12-23 07:13:34 +03:00
"intPtr", "int8Ptr", "int16Ptr", "int32Ptr", "int64Ptr",
"uintPtr", "uint8Ptr", "uint16Ptr", "uint32Ptr", "uint64Ptr",
2020-12-25 10:06:25 +03:00
"float32Ptr", "float64Ptr", "boolPtr", "stringPtr", "escapedStringPtr", "bytesPtr",
2020-12-23 07:13:34 +03:00
"intNPtr", "int8NPtr", "int16NPtr", "int32NPtr", "int64NPtr",
"uintNPtr", "uint8NPtr", "uint16NPtr", "uint32NPtr", "uint64NPtr",
2020-12-25 10:06:25 +03:00
"float32NPtr", "float64NPtr", "boolNPtr", "stringNPtr", "escapedStringNPtr", "bytesNPtr",
2020-08-15 11:41:38 +03:00
}
primitiveTypesUpper := []string{}
for _, typ := range primitiveTypes {
primitiveTypesUpper = append(primitiveTypesUpper, strings.ToUpper(string(typ[0]))+typ[1:])
}
opTypes := []opType{
2020-12-25 10:06:25 +03:00
createOpType("End", "Op"),
createOpType("Interface", "Op"),
createOpType("InterfaceEnd", "Op"),
createOpType("Ptr", "Op"),
createOpType("NPtr", "Op"),
createOpType("SliceHead", "SliceHead"),
createOpType("RootSliceHead", "SliceHead"),
createOpType("SliceElem", "SliceElem"),
createOpType("RootSliceElem", "SliceElem"),
createOpType("SliceEnd", "Op"),
createOpType("ArrayHead", "ArrayHead"),
createOpType("ArrayElem", "ArrayElem"),
createOpType("ArrayEnd", "Op"),
createOpType("MapHead", "MapHead"),
createOpType("MapHeadLoad", "MapHead"),
createOpType("MapKey", "MapKey"),
createOpType("MapValue", "MapValue"),
createOpType("MapEnd", "Op"),
createOpType("StructFieldRecursiveEnd", "Op"),
2020-12-29 18:13:45 +03:00
createOpType("StructAnonymousEnd", "StructEnd"),
2020-08-15 11:41:38 +03:00
}
for _, typ := range primitiveTypesUpper {
2020-12-25 10:06:25 +03:00
typ := typ
2020-12-25 10:38:18 +03:00
optype := createOpType(typ, "Op")
switch typ {
case "String", "StringPtr", "StringNPtr":
optype.Escaped = func() string {
return fmt.Sprintf("Escaped%s", typ)
}
}
opTypes = append(opTypes, optype)
2020-08-15 11:41:38 +03:00
}
2020-12-25 10:06:25 +03:00
for _, escapedOrNot := range []string{"", "Escaped"} {
for _, ptrOrNot := range []string{"", "Ptr", "NPtr"} {
for _, headType := range []string{"", "Anonymous"} {
for _, opt := range []string{"", "OmitEmpty", "StringTag"} {
for _, typ := range append(primitiveTypesUpper, "") {
escapedOrNot := escapedOrNot
ptrOrNot := ptrOrNot
headType := headType
opt := opt
typ := typ
op := fmt.Sprintf(
"Struct%sField%s%sHead%s%s",
escapedOrNot,
ptrOrNot,
headType,
opt,
typ,
)
opTypes = append(opTypes, opType{
Op: op,
Code: "StructField",
Indent: func() string { return fmt.Sprintf("%sIndent", op) },
2020-12-25 10:38:18 +03:00
Escaped: func() string {
switch typ {
case "String", "StringPtr", "StringNPtr":
return fmt.Sprintf(
"StructEscapedField%s%sHead%sEscaped%s",
ptrOrNot,
headType,
opt,
typ,
)
}
return fmt.Sprintf(
"StructEscapedField%s%sHead%s%s",
ptrOrNot,
headType,
opt,
typ,
)
},
2020-12-25 10:06:25 +03:00
HeadToPtrHead: func() string {
return fmt.Sprintf(
"Struct%sFieldPtr%sHead%s%s",
escapedOrNot,
headType,
opt,
typ,
)
},
HeadToNPtrHead: func() string {
return fmt.Sprintf(
"Struct%sFieldNPtr%sHead%s%s",
escapedOrNot,
headType,
opt,
typ,
)
},
HeadToAnonymousHead: func() string {
return fmt.Sprintf(
"Struct%sField%sAnonymousHead%s%s",
escapedOrNot,
ptrOrNot,
opt,
typ,
)
},
HeadToOmitEmptyHead: func() string {
return fmt.Sprintf(
"Struct%sField%s%sHeadOmitEmpty%s",
escapedOrNot,
ptrOrNot,
headType,
typ,
)
},
HeadToStringTagHead: func() string {
return fmt.Sprintf(
"Struct%sField%s%sHeadStringTag%s",
escapedOrNot,
ptrOrNot,
headType,
typ,
)
},
2021-01-08 20:28:33 +03:00
HeadToOnlyHead: func() string {
2021-01-08 20:35:37 +03:00
switch typ {
case "", "Array", "Map", "MapLoad", "Slice",
"Struct", "Recursive", "MarshalJSON", "MarshalText",
"IntString", "Int8String", "Int16String", "Int32String", "Int64String",
"UintString", "Uint8String", "Uint16String", "Uint32String", "Uint64String":
return op
}
2021-01-08 20:28:33 +03:00
return fmt.Sprintf(
"Struct%sField%s%sHead%sOnly",
escapedOrNot,
ptrOrNot,
headType,
typ,
)
},
2020-12-25 10:06:25 +03:00
PtrHeadToHead: func() string {
return fmt.Sprintf(
"Struct%sField%sHead%s%s",
escapedOrNot,
headType,
opt,
typ,
)
},
2020-12-29 18:13:45 +03:00
FieldToEnd: func() string { return op },
2020-12-25 10:06:25 +03:00
FieldToOmitEmptyField: func() string { return op },
FieldToStringTagField: func() string { return op },
})
}
}
}
2020-08-15 11:41:38 +03:00
}
}
2021-01-08 20:28:33 +03:00
for _, escapedOrNot := range []string{"", "Escaped"} {
for _, ptrOrNot := range []string{"", "Ptr", "NPtr"} {
for _, headType := range []string{"", "Anonymous"} {
for _, opt := range []string{"", "OmitEmpty", "StringTag"} {
for _, typ := range []string{
"", "Int", "Int8", "Int16", "Int32", "Int64",
"Uint", "Uint8", "Uint16", "Uint32", "Uint64",
"Float32", "Float64", "Bool", "String", "EscapedString", "Bytes",
"IntPtr", "Int8Ptr", "Int16Ptr", "Int32Ptr", "Int64Ptr",
"UintPtr", "Uint8Ptr", "Uint16Ptr", "Uint32Ptr", "Uint64Ptr",
"Float32Ptr", "Float64Ptr", "BoolPtr", "StringPtr", "EscapedStringPtr", "BytesPtr",
"IntNPtr", "Int8NPtr", "Int16NPtr", "Int32NPtr", "Int64NPtr",
"UintNPtr", "Uint8NPtr", "Uint16NPtr", "Uint32NPtr", "Uint64NPtr",
"Float32NPtr", "Float64NPtr", "BoolNPtr", "StringNPtr", "EscapedStringNPtr", "BytesNPtr",
} {
escapedOrNot := escapedOrNot
ptrOrNot := ptrOrNot
headType := headType
opt := opt
typ := typ
op := fmt.Sprintf(
"Struct%sField%s%sHead%s%sOnly",
escapedOrNot,
ptrOrNot,
headType,
opt,
typ,
)
opTypes = append(opTypes, opType{
Op: op,
Code: "StructField",
Indent: func() string { return fmt.Sprintf("%sIndent", op) },
Escaped: func() string {
switch typ {
case "String", "StringPtr", "StringNPtr":
return fmt.Sprintf(
"StructEscapedField%s%sHead%sEscaped%sOnly",
ptrOrNot,
headType,
opt,
typ,
)
}
return fmt.Sprintf(
"StructEscapedField%s%sHead%s%sOnly",
ptrOrNot,
headType,
opt,
typ,
)
},
HeadToPtrHead: func() string {
return fmt.Sprintf(
"Struct%sFieldPtr%sHead%s%sOnly",
escapedOrNot,
headType,
opt,
typ,
)
},
HeadToNPtrHead: func() string {
return fmt.Sprintf(
"Struct%sFieldNPtr%sHead%s%sOnly",
escapedOrNot,
headType,
opt,
typ,
)
},
HeadToAnonymousHead: func() string {
return fmt.Sprintf(
"Struct%sField%sAnonymousHead%s%sOnly",
escapedOrNot,
ptrOrNot,
opt,
typ,
)
},
HeadToOmitEmptyHead: func() string {
return fmt.Sprintf(
"Struct%sField%s%sHeadOmitEmpty%sOnly",
escapedOrNot,
ptrOrNot,
headType,
typ,
)
},
HeadToStringTagHead: func() string {
return fmt.Sprintf(
"Struct%sField%s%sHeadStringTag%sOnly",
escapedOrNot,
ptrOrNot,
headType,
typ,
)
},
PtrHeadToHead: func() string {
return fmt.Sprintf(
"Struct%sField%sHead%s%sOnly",
escapedOrNot,
headType,
opt,
typ,
)
},
HeadToOnlyHead: func() string { return op },
FieldToEnd: func() string { return op },
FieldToOmitEmptyField: func() string { return op },
FieldToStringTagField: func() string { return op },
})
}
}
}
}
}
2020-12-25 10:06:25 +03:00
for _, escapedOrNot := range []string{"", "Escaped"} {
for _, opt := range []string{"", "OmitEmpty", "StringTag"} {
for _, typ := range append(primitiveTypesUpper, "") {
escapedOrNot := escapedOrNot
opt := opt
typ := typ
2020-08-15 11:41:38 +03:00
2020-12-25 10:06:25 +03:00
op := fmt.Sprintf(
"Struct%sField%s%s",
escapedOrNot,
opt,
typ,
)
opTypes = append(opTypes, opType{
2020-12-25 10:38:18 +03:00
Op: op,
Code: "StructField",
Indent: func() string { return fmt.Sprintf("%sIndent", op) },
Escaped: func() string {
switch typ {
case "String", "StringPtr", "StringNPtr":
return fmt.Sprintf(
"StructEscapedField%sEscaped%s",
opt,
typ,
)
}
return fmt.Sprintf(
"StructEscapedField%s%s",
opt,
typ,
)
},
2020-12-25 10:06:25 +03:00
HeadToPtrHead: func() string { return op },
HeadToNPtrHead: func() string { return op },
HeadToAnonymousHead: func() string { return op },
HeadToOmitEmptyHead: func() string { return op },
HeadToStringTagHead: func() string { return op },
2021-01-08 20:28:33 +03:00
HeadToOnlyHead: func() string { return op },
2020-12-25 10:06:25 +03:00
PtrHeadToHead: func() string { return op },
2020-12-29 18:13:45 +03:00
FieldToEnd: func() string {
switch typ {
2020-12-29 19:29:29 +03:00
case "", "Array", "Map", "MapLoad", "Slice", "Struct", "Recursive":
2020-12-29 18:13:45 +03:00
return op
}
return fmt.Sprintf(
"Struct%sEnd%s%s",
escapedOrNot,
opt,
typ,
)
},
2020-12-25 10:06:25 +03:00
FieldToOmitEmptyField: func() string {
return fmt.Sprintf(
"Struct%sFieldOmitEmpty%s",
escapedOrNot,
typ,
)
},
FieldToStringTagField: func() string {
return fmt.Sprintf(
"Struct%sFieldStringTag%s",
escapedOrNot,
typ,
)
},
})
}
}
2020-08-15 11:41:38 +03:00
}
2020-12-29 17:17:15 +03:00
for _, escapedOrNot := range []string{"", "Escaped"} {
for _, opt := range []string{"", "OmitEmpty", "StringTag"} {
for _, typ := range append(primitiveTypesUpper, "") {
escapedOrNot := escapedOrNot
opt := opt
typ := typ
op := fmt.Sprintf(
"Struct%sEnd%s%s",
escapedOrNot,
opt,
typ,
)
opTypes = append(opTypes, opType{
Op: op,
2020-12-29 18:13:45 +03:00
Code: "StructEnd",
2020-12-29 17:17:15 +03:00
Indent: func() string { return fmt.Sprintf("%sIndent", op) },
Escaped: func() string {
switch typ {
case "String", "StringPtr", "StringNPtr":
return fmt.Sprintf(
"StructEscapedEnd%sEscaped%s",
opt,
typ,
)
}
return fmt.Sprintf(
"StructEscapedEnd%s%s",
opt,
typ,
)
},
2020-12-29 18:13:45 +03:00
HeadToPtrHead: func() string { return op },
HeadToNPtrHead: func() string { return op },
HeadToAnonymousHead: func() string { return op },
HeadToOmitEmptyHead: func() string { return op },
HeadToStringTagHead: func() string { return op },
2021-01-08 20:28:33 +03:00
HeadToOnlyHead: func() string { return op },
2020-12-29 18:13:45 +03:00
PtrHeadToHead: func() string { return op },
FieldToEnd: func() string { return op },
FieldToOmitEmptyField: func() string { return op },
FieldToStringTagField: func() string { return op },
2020-12-29 17:17:15 +03:00
})
}
}
}
2020-12-25 10:06:25 +03:00
indentOpTypes := []opType{}
for _, typ := range opTypes {
typ := typ
indentOpTypes = append(indentOpTypes, opType{
2020-12-25 10:38:18 +03:00
Op: fmt.Sprintf("%sIndent", typ.Op),
Code: typ.Code,
Indent: func() string { return fmt.Sprintf("%sIndent", typ.Op) },
Escaped: func() string { return fmt.Sprintf("%sIndent", typ.Escaped()) },
2020-12-25 10:06:25 +03:00
HeadToPtrHead: func() string {
return fmt.Sprintf("%sIndent", typ.HeadToPtrHead())
},
HeadToNPtrHead: func() string {
return fmt.Sprintf("%sIndent", typ.HeadToNPtrHead())
},
HeadToAnonymousHead: func() string {
return fmt.Sprintf("%sIndent", typ.HeadToAnonymousHead())
},
HeadToOmitEmptyHead: func() string {
return fmt.Sprintf("%sIndent", typ.HeadToOmitEmptyHead())
},
HeadToStringTagHead: func() string {
return fmt.Sprintf("%sIndent", typ.HeadToStringTagHead())
},
2021-01-08 20:28:33 +03:00
HeadToOnlyHead: func() string {
return fmt.Sprintf("%sIndent", typ.HeadToOnlyHead())
},
2020-12-25 10:06:25 +03:00
PtrHeadToHead: func() string {
return fmt.Sprintf("%sIndent", typ.PtrHeadToHead())
},
FieldToOmitEmptyField: func() string {
return fmt.Sprintf("%sIndent", typ.FieldToOmitEmptyField())
},
FieldToStringTagField: func() string {
return fmt.Sprintf("%sIndent", typ.FieldToStringTagField())
},
2020-12-29 18:13:45 +03:00
FieldToEnd: func() string {
return fmt.Sprintf("%sIndent", typ.FieldToEnd())
},
2020-08-15 11:41:38 +03:00
})
}
var b bytes.Buffer
if err := tmpl.Execute(&b, struct {
2020-12-30 10:09:12 +03:00
CodeTypes []string
OpTypes []opType
OpNotIndentTypes []opType
OpLen int
OpIndentLen int
2020-08-15 11:41:38 +03:00
}{
2020-12-30 10:09:12 +03:00
CodeTypes: codeTypes,
OpTypes: append(opTypes, indentOpTypes...),
OpNotIndentTypes: opTypes,
OpLen: len(opTypes),
OpIndentLen: len(indentOpTypes),
2020-08-15 11:41:38 +03:00
}); err != nil {
return err
}
path := filepath.Join(repoRoot(), "encode_optype.go")
2020-11-12 18:25:57 +03:00
buf, err := format.Source(b.Bytes())
if err != nil {
return err
}
return ioutil.WriteFile(path, buf, 0644)
2020-08-15 11:41:38 +03:00
}
func repoRoot() string {
_, file, _, _ := runtime.Caller(0)
relativePathFromRepoRoot := filepath.Join("cmd", "generator")
return strings.TrimSuffix(filepath.Dir(file), relativePathFromRepoRoot)
}
func main() {
if err := _main(); err != nil {
panic(err)
}
}