diff --git a/cmd/README.md b/cmd/README.md new file mode 100644 index 0000000..854e525 --- /dev/null +++ b/cmd/README.md @@ -0,0 +1,22 @@ +## cmd/karmem + +This folder contains files related to the karmem cli tool. The `cmd/karmem` is equivalent of +`protoc` or `flatc`. That is designed to be used as a command line tool, in order to read +karmem files and generate code for the corresponding languages. + +## Usage + +You can run this program with `go run karmem.org/cmd/karmem help`. + +## Structure + +- kmcheck: + - This package will verify if the parsed karmem file (from the `kmparser` package) contains +any potential conflict, or use any or uses any deprecated features. +- kmgen: + - This generates code for multiple languages. That will read the parsed +file (from the `kmparser` package) and generates the code for the given language. +- kmparser: + - This package is responsible to read karmem schema file. That package is +language independent. +- main.go: The main file for the karmem cli tool (that uses `kmparser`, `kmgen` and `kmcheck`). \ No newline at end of file diff --git a/cmd/karmem/kmcheck/assemblyscript.go b/cmd/karmem/kmcheck/assemblyscript.go new file mode 100644 index 0000000..b3ec831 --- /dev/null +++ b/cmd/karmem/kmcheck/assemblyscript.go @@ -0,0 +1,108 @@ +package kmcheck + +import ( + "sync" + + "karmem.org/cmd/karmem/kmparser" +) + +func init() { RegisterValidator(NewAssemblyScript()) } + +type AssemblyScript struct { + RestrictedWords *RestrictedWords +} + +func (v *AssemblyScript) CheckStruct(mutex *sync.Mutex, parsed *kmparser.Content, target *kmparser.StructData) { + v.RestrictedWords.CheckStruct(mutex, parsed, target) +} + +func (v *AssemblyScript) CheckEnum(mutex *sync.Mutex, parsed *kmparser.Content, target *kmparser.EnumData) { + v.RestrictedWords.CheckEnum(mutex, parsed, target) +} + +func NewAssemblyScript() *AssemblyScript { + return &AssemblyScript{ + RestrictedWords: &RestrictedWords{ + Language: kmparser.LanguageAssemblyScript, + Rules: []WordRule{ + NewMatchRule("await"), + NewMatchRule("break"), + NewMatchRule("case"), + NewMatchRule("catch"), + NewMatchRule("class"), + NewMatchRule("const"), + NewMatchRule("continue"), + NewMatchRule("debugger"), + NewMatchRule("default"), + NewMatchRule("delete"), + NewMatchRule("do"), + NewMatchRule("else"), + NewMatchRule("enum"), + NewMatchRule("export"), + NewMatchRule("extends"), + NewMatchRule("false"), + NewMatchRule("finally"), + NewMatchRule("for"), + NewMatchRule("function"), + NewMatchRule("if"), + NewMatchRule("import"), + NewMatchRule("in"), + NewMatchRule("of"), + NewMatchRule("instanceof"), + NewMatchRule("new"), + NewMatchRule("null"), + NewMatchRule("return"), + NewMatchRule("super"), + NewMatchRule("switch"), + NewMatchRule("this"), + NewMatchRule("throw"), + NewMatchRule("true"), + NewMatchRule("try"), + NewMatchRule("typeof"), + NewMatchRule("type"), + NewMatchRule("var"), + NewMatchRule("void"), + NewMatchRule("while"), + NewMatchRule("with"), + NewMatchRule("yield"), + NewMatchRule("let"), + NewMatchRule("static"), + NewMatchRule("as"), + NewMatchRule("any"), + NewMatchRule("set"), + NewMatchRule("from"), + NewMatchRule("constructor"), + NewMatchRule("module"), + NewMatchRule("require"), + NewMatchRule("implements"), + NewMatchRule("interface"), + NewMatchRule("package"), + NewMatchRule("private"), + NewMatchRule("protected"), + NewMatchRule("and"), + NewMatchRule("public"), + NewMatchRule("i8"), + NewMatchRule("i16"), + NewMatchRule("i32"), + NewMatchRule("i64"), + NewMatchRule("u8"), + NewMatchRule("u16"), + NewMatchRule("u32"), + NewMatchRule("u64"), + NewMatchRule("f32"), + NewMatchRule("f64"), + NewMatchRule("bool"), + NewMatchRule("boolean"), + NewMatchRule("isize"), + NewMatchRule("usize"), + NewMatchRule("v128"), + NewMatchRule("externref"), + NewMatchRule("funcref"), + NewMatchRule("string"), + NewMatchRule("number"), + NewMatchRule("symbol"), + NewMatchRule("undefined"), + }, + }, + } +} diff --git a/cmd/karmem/kmcheck/c.go b/cmd/karmem/kmcheck/c.go new file mode 100644 index 0000000..d86f647 --- /dev/null +++ b/cmd/karmem/kmcheck/c.go @@ -0,0 +1,83 @@ +package kmcheck + +import ( + "sync" + + "karmem.org/cmd/karmem/kmparser" +) + +func init() { RegisterValidator(NewC()) } + +type C struct { + RestrictedWords *RestrictedWords + CollisionArraySuffix *CollisionArraySuffix +} + +func (v *C) CheckStruct(mutex *sync.Mutex, parsed *kmparser.Content, target *kmparser.StructData) { + v.RestrictedWords.CheckStruct(mutex, parsed, target) + +} + +func (v *C) CheckEnum(mutex *sync.Mutex, parsed *kmparser.Content, target *kmparser.EnumData) { + v.RestrictedWords.CheckEnum(mutex, parsed, target) +} + +func NewC() *C { + return &C{ + RestrictedWords: &RestrictedWords{ + Language: kmparser.LanguageC, + Rules: []WordRule{ + NewMatchRule("auto"), + NewMatchRule("else"), + NewMatchRule("long"), + NewMatchRule("switch"), + NewMatchRule("break"), + NewMatchRule("enum"), + NewMatchRule("register"), + NewMatchRule("typedef"), + NewMatchRule("case"), + NewMatchRule("extern"), + NewMatchRule("return"), + NewMatchRule("union"), + NewMatchRule("char"), + NewMatchRule("float"), + NewMatchRule("short"), + NewMatchRule("unsigned"), + NewMatchRule("const"), + NewMatchRule("for"), + NewMatchRule("signed"), + NewMatchRule("void"), + NewMatchRule("continue"), + NewMatchRule("goto"), + NewMatchRule("sizeof"), + NewMatchRule("volatile"), + NewMatchRule("default"), + NewMatchRule("if"), + NewMatchRule("static"), + NewMatchRule("while"), + NewMatchRule("do"), + NewMatchRule("int"), + NewMatchRule("struct"), + NewMatchRule("double"), + NewMatchRegexRule("^int[0-9]+_t$"), + NewMatchRegexRule("^uint[0-9]+_t$"), + NewMatchRegexRule("^int_fast[0-9]+_t$"), + NewMatchRegexRule("^uint_fast[0-9]+_t$"), + NewMatchRegexRule("^int_least[0-9]+_t$"), + NewMatchRegexRule("^uint_least[0-9]+_t$"), + NewMatchRegexRule("true"), + NewMatchRegexRule("false"), + NewMatchRegexRule("null"), + NewMatchRegexRule("bool"), + }, + }, + CollisionArraySuffix: &CollisionArraySuffix{ + Language: kmparser.LanguageC, + Rules: []WordRule{ + NewMatchSuffix("size"), + NewMatchSuffix("pointer"), + NewMatchSuffix("length"), + }, + }, + } +} diff --git a/cmd/karmem/kmcheck/dotnet.go b/cmd/karmem/kmcheck/dotnet.go new file mode 100644 index 0000000..1bc4dce --- /dev/null +++ b/cmd/karmem/kmcheck/dotnet.go @@ -0,0 +1,155 @@ +package kmcheck + +import ( + "sync" + + "karmem.org/cmd/karmem/kmparser" +) + +func init() { RegisterValidator(NewDotNet()) } + +type DotNet struct { + RestrictedWords *RestrictedWords + CollisionParentChildField *CollisionParentChildField +} + +func NewDotNet() *DotNet { + return &DotNet{ + RestrictedWords: &RestrictedWords{ + Language: kmparser.LanguageDotnet, + Rules: []WordRule{ + NewMatchRule("abstract"), + NewMatchRule("as"), + NewMatchRule("base"), + NewMatchRule("bool"), + NewMatchRule("break"), + NewMatchRule("byte"), + NewMatchRule("case"), + NewMatchRule("catch"), + NewMatchRule("char"), + NewMatchRule("checked"), + NewMatchRule("class"), + NewMatchRule("const"), + NewMatchRule("continue"), + NewMatchRule("decimal"), + NewMatchRule("default"), + NewMatchRule("delegate"), + NewMatchRule("do"), + NewMatchRule("double"), + NewMatchRule("else"), + NewMatchRule("enum"), + NewMatchRule("event"), + NewMatchRule("explicit"), + NewMatchRule("extern"), + NewMatchRule("false"), + NewMatchRule("finally"), + NewMatchRule("fixed"), + NewMatchRule("float"), + NewMatchRule("for"), + NewMatchRule("foreach"), + NewMatchRule("goto"), + NewMatchRule("if"), + NewMatchRule("implicit"), + NewMatchRule("in"), + NewMatchRule("int"), + NewMatchRule("interface"), + NewMatchRule("internal"), + NewMatchRule("is"), + NewMatchRule("lock"), + NewMatchRule("long"), + NewMatchRule("namespace"), + NewMatchRule("new"), + NewMatchRule("null"), + NewMatchRule("object"), + NewMatchRule("operator"), + NewMatchRule("out"), + NewMatchRule("override"), + NewMatchRule("params"), + NewMatchRule("private"), + NewMatchRule("protected"), + NewMatchRule("public"), + NewMatchRule("readonly"), + NewMatchRule("ref"), + NewMatchRule("return"), + NewMatchRule("sbyte"), + NewMatchRule("sealed"), + NewMatchRule("short"), + NewMatchRule("sizeof"), + NewMatchRule("stackalloc"), + NewMatchRule("static"), + NewMatchRule("string"), + NewMatchRule("struct"), + NewMatchRule("switch"), + NewMatchRule("this"), + NewMatchRule("throw"), + NewMatchRule("true"), + NewMatchRule("try"), + NewMatchRule("typeof"), + NewMatchRule("uint"), + NewMatchRule("ulong"), + NewMatchRule("unchecked"), + NewMatchRule("unsafe"), + NewMatchRule("ushort"), + NewMatchRule("using"), + NewMatchRule("virtual"), + NewMatchRule("void"), + NewMatchRule("volatile"), + NewMatchRule("while"), + NewMatchRule("add"), + NewMatchRule("and"), + NewMatchRule("alias"), + NewMatchRule("ascending"), + NewMatchRule("args"), + NewMatchRule("async"), + NewMatchRule("await"), + NewMatchRule("by"), + NewMatchRule("descending"), + NewMatchRule("dynamic"), + NewMatchRule("equals"), + NewMatchRule("from"), + NewMatchRule("get"), + NewMatchRule("global"), + NewMatchRule("group"), + NewMatchRule("init"), + NewMatchRule("into"), + NewMatchRule("join"), + NewMatchRule("let"), + NewMatchRule("managed"), + NewMatchRule("nameof"), + NewMatchRule("nint"), + NewMatchRule("not"), + NewMatchRule("notnull"), + NewMatchRule("nuint"), + NewMatchRule("on"), + NewMatchRule("or"), + NewMatchRule("orderby"), + NewMatchRule("partial"), + NewMatchRule("record"), + NewMatchRule("remove"), + NewMatchRule("required"), + NewMatchRule("select"), + NewMatchRule("set"), + NewMatchRule("unmanage"), + NewMatchRule("value"), + NewMatchRule("var"), + NewMatchRule("when "), + NewMatchRule("where"), + NewMatchRule("with"), + NewMatchRule("yield"), + }, + }, + CollisionParentChildField: &CollisionParentChildField{ + Language: kmparser.LanguageDotnet, + }, + } +} + +func (v *DotNet) CheckStruct(mutex *sync.Mutex, parsed *kmparser.Content, target *kmparser.StructData) { + v.RestrictedWords.CheckStruct(mutex, parsed, target) + v.CollisionParentChildField.CheckStruct(mutex, parsed, target) +} + +func (v *DotNet) CheckEnum(mutex *sync.Mutex, parsed *kmparser.Content, target *kmparser.EnumData) { + v.RestrictedWords.CheckEnum(mutex, parsed, target) + v.CollisionParentChildField.CheckEnum(mutex, parsed, target) +} diff --git a/cmd/karmem/kmcheck/general.go b/cmd/karmem/kmcheck/general.go new file mode 100644 index 0000000..8e475f9 --- /dev/null +++ b/cmd/karmem/kmcheck/general.go @@ -0,0 +1,152 @@ +package kmcheck + +import ( + "fmt" + "regexp" + "strings" + "sync" + + "karmem.org/cmd/karmem/kmparser" +) + +type WordRule func(needle string) bool + +func NewMatchRule(match string) WordRule { + return func(needle string) bool { + return strings.EqualFold(match, needle) + } +} + +func NewMatchRegexRule(reg string) WordRule { + r := regexp.MustCompile(reg) + return func(needle string) bool { + return r.MatchString(strings.ToLower(needle)) + } +} + +func NewMatchPrefix(match string) WordRule { + return func(needle string) bool { + return strings.HasPrefix(match, strings.ToLower(needle)) + } +} + +func NewMatchSuffix(match string) WordRule { + return func(needle string) bool { + return strings.HasSuffix(match, strings.ToLower(needle)) + } +} + +type RestrictedWords struct { + Language kmparser.Language + Rules []WordRule +} + +func (r *RestrictedWords) newWarning(mutex *sync.Mutex, k *[]kmparser.Warning, msg string) { + mutex.Lock() + defer mutex.Unlock() + + *k = append(*k, kmparser.Warning{Data: kmparser.WarningData{ + Message: msg, + Rule: "RestrictedWords", + Type: kmparser.RuleTypeReservedName, + Languages: r.Language, + }}) +} + +func (r *RestrictedWords) CheckStruct(mutex *sync.Mutex, parsed *kmparser.Content, target *kmparser.StructData) { + for _, word := range r.Rules { + if word(target.Name) { + r.newWarning(mutex, &target.Warnings, fmt.Sprintf("%s is a restricted name", target.Name)) + } + for i := range target.Fields { + field := &target.Fields[i] + if word(field.Data.Name) { + r.newWarning(mutex, &field.Data.Warnings, fmt.Sprintf("%s is a restricted name", field.Data.Name)) + } + } + } +} + +func (r *RestrictedWords) CheckEnum(mutex *sync.Mutex, parsed *kmparser.Content, target *kmparser.EnumData) { + for _, word := range r.Rules { + if word(target.Name) { + r.newWarning(mutex, &target.Warnings, fmt.Sprintf("%s is a restricted name", target.Name)) + } + for i := range target.Fields { + field := &target.Fields[i] + if word(field.Data.Name) { + r.newWarning(mutex, &field.Data.Warnings, fmt.Sprintf("%s is a restricted name", field.Data.Name)) + } + } + } +} + +type CollisionParentChildField struct { + Language kmparser.Language +} + +func (r *CollisionParentChildField) newWarning(mutex *sync.Mutex, k *[]kmparser.Warning, msg string) { + mutex.Lock() + defer mutex.Unlock() + + *k = append(*k, kmparser.Warning{Data: kmparser.WarningData{ + Message: msg, + Rule: "FieldNameMatchesStructName", + Type: kmparser.RuleTypeDuplicateName, + Languages: r.Language, + }}) +} + +func (r *CollisionParentChildField) CheckStruct(mutex *sync.Mutex, parsed *kmparser.Content, target *kmparser.StructData) { + for i := range target.Fields { + x := &target.Fields[i] + if target.Name == x.Data.Name { + r.newWarning(mutex, &x.Data.Warnings, fmt.Sprintf("%s is the same name of parent struct", target.Name)) + } + } +} + +func (r *CollisionParentChildField) CheckEnum(mutex *sync.Mutex, parsed *kmparser.Content, target *kmparser.EnumData) { + for i := range target.Fields { + x := &target.Fields[i] + if target.Name == x.Data.Name { + r.newWarning(mutex, &target.Warnings, fmt.Sprintf("%s is the same name of parent enum", target.Name)) + } + } +} + +type CollisionArraySuffix struct { + Language kmparser.Language + Rules []WordRule +} + +func (r *CollisionArraySuffix) newWarning(mutex *sync.Mutex, k *[]kmparser.Warning, msg string) { + mutex.Lock() + defer mutex.Unlock() + *k = append(*k, kmparser.Warning{Data: kmparser.WarningData{ + Message: msg, + Rule: "", + Type: kmparser.RuleTypeDuplicateName, + Languages: kmparser.LanguageC, + }}) +} + +func (r *CollisionArraySuffix) CheckStruct(mutex *sync.Mutex, parsed *kmparser.Content, target *kmparser.StructData) { + for i := range target.Fields { + x := &target.Fields[i] + for _, v := range r.Rules { + if !v(x.Data.Name) { + continue + } + for i := range target.Fields { + y := &target.Fields[i] + if strings.EqualFold(x.Data.Name, y.Data.Name) { + r.newWarning(mutex, &y.Data.Warnings, fmt.Sprintf("%s may collides with %s, the generated code may generate functions with such suffix", x.Data.Name, y.Data.Name)) + } + } + } + } +} + +func (r *CollisionArraySuffix) CheckEnum(mutex *sync.Mutex, parsed *kmparser.Content, target *kmparser.EnumData) { +} diff --git a/cmd/karmem/kmcheck/go.go b/cmd/karmem/kmcheck/go.go new file mode 100644 index 0000000..8845133 --- /dev/null +++ b/cmd/karmem/kmcheck/go.go @@ -0,0 +1,91 @@ +package kmcheck + +import ( + "sync" + + "karmem.org/cmd/karmem/kmparser" +) + +func init() { RegisterValidator(NewGolang()) } + +type Golang struct { + RestrictedWords *RestrictedWords +} + +func (v *Golang) CheckStruct(mutex *sync.Mutex, parsed *kmparser.Content, target *kmparser.StructData) { + v.RestrictedWords.CheckStruct(mutex, parsed, target) +} + +func (v *Golang) CheckEnum(mutex *sync.Mutex, parsed *kmparser.Content, target *kmparser.EnumData) { + v.RestrictedWords.CheckEnum(mutex, parsed, target) +} + +func NewGolang() *Golang { + return &Golang{ + RestrictedWords: &RestrictedWords{ + Language: kmparser.LanguageGolang, + Rules: []WordRule{ + NewMatchRule("break"), + NewMatchRule("default"), + NewMatchRule("delete"), + NewMatchRule("func"), + NewMatchRule("interface"), + NewMatchRule("select"), + NewMatchRule("case"), + NewMatchRule("defer"), + NewMatchRule("go"), + NewMatchRule("map"), + NewMatchRule("struct"), + NewMatchRule("chan"), + NewMatchRule("else"), + NewMatchRule("goto"), + NewMatchRule("package"), + NewMatchRule("switch"), + NewMatchRule("const"), + NewMatchRule("fallthrough"), + NewMatchRule("if"), + NewMatchRule("range"), + NewMatchRule("type"), + NewMatchRule("continue"), + NewMatchRule("for"), + NewMatchRule("import"), + NewMatchRule("return"), + NewMatchRule("var"), + NewMatchRule("append"), + NewMatchRule("bool"), + NewMatchRule("byte"), + NewMatchRule("cap"), + NewMatchRule("close"), + NewMatchRule("complex"), + NewMatchRule("complex64"), + NewMatchRule("complex128"), + NewMatchRule("uint16"), + NewMatchRule("copy"), + NewMatchRule("false"), + NewMatchRule("float32"), + NewMatchRule("float64"), + NewMatchRule("imag"), + NewMatchRule("int"), + NewMatchRule("int8"), + NewMatchRule("int16"), + NewMatchRule("uint32"), + NewMatchRule("int32"), + NewMatchRule("int64"), + NewMatchRule("iota"), + NewMatchRule("len"), + NewMatchRule("make"), + NewMatchRule("new"), + NewMatchRule("nil"), + NewMatchRule("panic"), + NewMatchRule("uint64"), + NewMatchRule("real"), + NewMatchRule("recover"), + NewMatchRule("string"), + NewMatchRule("true"), + NewMatchRule("uint"), + NewMatchRule("uint8"), + NewMatchRule("uintptr"), + }, + }, + } +} diff --git a/cmd/karmem/kmcheck/karmem.go b/cmd/karmem/kmcheck/karmem.go new file mode 100644 index 0000000..61dfb99 --- /dev/null +++ b/cmd/karmem/kmcheck/karmem.go @@ -0,0 +1,33 @@ +package kmcheck + +import ( + "sync" + + "karmem.org/cmd/karmem/kmparser" +) + +func init() { RegisterValidator(NewKarmem()) } + +type Karmem struct { + RestrictedWords *RestrictedWords +} + +func NewKarmem() *Karmem { + return &Karmem{ + RestrictedWords: &RestrictedWords{ + Rules: []WordRule{ + NewMatchRule("KarmemPointer"), + NewMatchRule("KarmemSize"), + }, + }, + } +} + +func (v *Karmem) CheckStruct(mutex *sync.Mutex, parsed *kmparser.Content, target *kmparser.StructData) { + v.RestrictedWords.CheckStruct(mutex, parsed, target) + +} + +func (v *Karmem) CheckEnum(mutex *sync.Mutex, parsed *kmparser.Content, target *kmparser.EnumData) { + v.RestrictedWords.CheckEnum(mutex, parsed, target) +} diff --git a/cmd/karmem/kmcheck/kmcheck.go b/cmd/karmem/kmcheck/kmcheck.go new file mode 100644 index 0000000..d8370b4 --- /dev/null +++ b/cmd/karmem/kmcheck/kmcheck.go @@ -0,0 +1,48 @@ +package kmcheck + +import ( + "sync" + + "karmem.org/cmd/karmem/kmparser" +) + +// Validators is a list of all Validator available and registered by RegisterValidator +var Validators []Validator + +// RegisterValidator register the given Validator. +// You should use it on `init` function. +func RegisterValidator(v Validator) { + Validators = append(Validators, v) +} + +type Validator interface { + CheckStruct(mutex *sync.Mutex, parsed *kmparser.Content, target *kmparser.StructData) + CheckEnum(mutex *sync.Mutex, parsed *kmparser.Content, target *kmparser.EnumData) +} + +// Check checks potential naming conflicts and collisions, +// that function will return a list of warnings and also +// set into kmparser.Content. +func Check(parsed *kmparser.Content) []kmparser.Warning { + var ( + warnings []kmparser.Warning + mutex sync.Mutex + group sync.WaitGroup + ) + + for _, v := range Validators { + group.Add(1) + go func(v Validator) { + defer group.Done() + for i := range parsed.Structs { + v.CheckStruct(&mutex, parsed, &parsed.Structs[i].Data) + } + for i := range parsed.Enums { + v.CheckEnum(&mutex, parsed, &parsed.Enums[i].Data) + } + }(v) + } + + group.Wait() + return warnings +} diff --git a/cmd/karmem/kmcheck/odin.go b/cmd/karmem/kmcheck/odin.go new file mode 100644 index 0000000..06e4bf6 --- /dev/null +++ b/cmd/karmem/kmcheck/odin.go @@ -0,0 +1,32 @@ +package kmcheck + +import ( + "sync" + + "karmem.org/cmd/karmem/kmparser" +) + +func init() { RegisterValidator(NewOdin()) } + +type Odin struct { + RestrictedWords *RestrictedWords +} + +func (v *Odin) CheckStruct(mutex *sync.Mutex, parsed *kmparser.Content, target *kmparser.StructData) { + v.RestrictedWords.CheckStruct(mutex, parsed, target) +} + +func (v *Odin) CheckEnum(mutex *sync.Mutex, parsed *kmparser.Content, target *kmparser.EnumData) { + v.RestrictedWords.CheckEnum(mutex, parsed, target) +} + +func NewOdin() *Odin { + return &Odin{ + RestrictedWords: &RestrictedWords{ + Language: kmparser.LanguageOdin, + Rules: []WordRule{ + // TODO: Add rules for Odin. + }, + }, + } +} diff --git a/cmd/karmem/kmcheck/swift.go b/cmd/karmem/kmcheck/swift.go new file mode 100644 index 0000000..2d63759 --- /dev/null +++ b/cmd/karmem/kmcheck/swift.go @@ -0,0 +1,124 @@ +package kmcheck + +import ( + "sync" + + "karmem.org/cmd/karmem/kmparser" +) + +func init() { RegisterValidator(NewSwift()) } + +type Swift struct { + RestrictedWords *RestrictedWords +} + +func (v *Swift) CheckStruct(mutex *sync.Mutex, parsed *kmparser.Content, target *kmparser.StructData) { + v.RestrictedWords.CheckStruct(mutex, parsed, target) +} + +func (v *Swift) CheckEnum(mutex *sync.Mutex, parsed *kmparser.Content, target *kmparser.EnumData) { + v.RestrictedWords.CheckEnum(mutex, parsed, target) +} + +func NewSwift() *Swift { + return &Swift{ + RestrictedWords: &RestrictedWords{ + Language: kmparser.LanguageSwift, + Rules: []WordRule{ + NewMatchRule("associatedtype"), + NewMatchRule("class"), + NewMatchRule("deinit"), + NewMatchRule("enum"), + NewMatchRule("extension"), + NewMatchRule("fileprivate"), + NewMatchRule("func"), + NewMatchRule("import"), + NewMatchRule("init"), + NewMatchRule("inout"), + NewMatchRule("internal"), + NewMatchRule("let"), + NewMatchRule("open"), + NewMatchRule("operator"), + NewMatchRule("private"), + NewMatchRule("precedencegroup"), + NewMatchRule("protocol"), + NewMatchRule("public"), + NewMatchRule("rethrows"), + NewMatchRule("static"), + NewMatchRule("struct"), + NewMatchRule("subscript"), + NewMatchRule("typealias"), + NewMatchRule("var"), + NewMatchRule("break"), + NewMatchRule("case"), + NewMatchRule("catch"), + NewMatchRule("continue"), + NewMatchRule("default"), + NewMatchRule("defer"), + NewMatchRule("do"), + NewMatchRule("else"), + NewMatchRule("fallthrough"), + NewMatchRule("for"), + NewMatchRule("guard"), + NewMatchRule("if"), + NewMatchRule("in"), + NewMatchRule("repeat"), + NewMatchRule("return"), + NewMatchRule("throw"), + NewMatchRule("switch"), + NewMatchRule("where"), + NewMatchRule("while"), + NewMatchRule("Any"), + NewMatchRule("as"), + NewMatchRule("catch"), + NewMatchRule("false"), + NewMatchRule("is"), + NewMatchRule("nil"), + NewMatchRule("rethrows"), + NewMatchRule("self"), + NewMatchRule("Self"), + NewMatchRule("super"), + NewMatchRule("throw"), + NewMatchRule("throws"), + NewMatchRule("true"), + NewMatchRule("try"), + NewMatchRule("_"), + NewMatchRule("associativity"), + NewMatchRule("convenience"), + NewMatchRule("didSet"), + NewMatchRule("dynamic"), + NewMatchRule("final"), + NewMatchRule("get"), + NewMatchRule("indirect"), + NewMatchRule("infix"), + NewMatchRule("lazy"), + NewMatchRule("left"), + NewMatchRule("mutating"), + NewMatchRule("none"), + NewMatchRule("nonmutating"), + NewMatchRule("optional"), + NewMatchRule("override"), + NewMatchRule("postfix"), + NewMatchRule("precedence"), + NewMatchRule("prefix"), + NewMatchRule("Protocol"), + NewMatchRule("required"), + NewMatchRule("right"), + NewMatchRule("set"), + NewMatchRule("some"), + NewMatchRule("Type"), + NewMatchRule("unowned"), + NewMatchRule("weak"), + NewMatchRule("willSet"), + NewMatchRegexRule("^Int[0-9]+$"), + NewMatchRegexRule("^Uint[0-9]+$"), + NewMatchRegexRule("^Float[0-9]+$"), + NewMatchRule("Float"), + NewMatchRule("Double"), + NewMatchRule("Bool"), + NewMatchRule("Void"), + NewMatchRule("String"), + }, + }, + } +} diff --git a/cmd/karmem/kmcheck/zig.go b/cmd/karmem/kmcheck/zig.go new file mode 100644 index 0000000..3514c74 --- /dev/null +++ b/cmd/karmem/kmcheck/zig.go @@ -0,0 +1,114 @@ +package kmcheck + +import ( + "sync" + + "karmem.org/cmd/karmem/kmparser" +) + +func init() { RegisterValidator(NewZig()) } + +type Zig struct { + RestrictedWords *RestrictedWords +} + +func (v *Zig) CheckStruct(mutex *sync.Mutex, parsed *kmparser.Content, target *kmparser.StructData) { + v.RestrictedWords.CheckStruct(mutex, parsed, target) +} + +func (v *Zig) CheckEnum(mutex *sync.Mutex, parsed *kmparser.Content, target *kmparser.EnumData) { + v.RestrictedWords.CheckEnum(mutex, parsed, target) +} + +func NewZig() *Zig { + return &Zig{ + RestrictedWords: &RestrictedWords{ + Language: kmparser.LanguageZig, + Rules: []WordRule{ + NewMatchRule("align"), + NewMatchRule("allowzero"), + NewMatchRule("and"), + NewMatchRule("anyframe"), + NewMatchRule("anytype"), + NewMatchRule("asm"), + NewMatchRule("async"), + NewMatchRule("await"), + NewMatchRule("break"), + NewMatchRule("catch"), + NewMatchRule("comptime"), + NewMatchRule("const"), + NewMatchRule("continue"), + NewMatchRule("defer"), + NewMatchRule("else"), + NewMatchRule("enum"), + NewMatchRule("errdefer"), + NewMatchRule("error"), + NewMatchRule("export"), + NewMatchRule("extern"), + NewMatchRule("false"), + NewMatchRule("fn"), + NewMatchRule("for"), + NewMatchRule("if"), + NewMatchRule("inline"), + NewMatchRule("noalias"), + NewMatchRule("nosuspend"), + NewMatchRule("null"), + NewMatchRule("or"), + NewMatchRule("orelse"), + NewMatchRule("packed"), + NewMatchRule("pub"), + NewMatchRule("resume"), + NewMatchRule("return"), + NewMatchRule("linksection"), + NewMatchRule("struct"), + NewMatchRule("suspend"), + NewMatchRule("switch"), + NewMatchRule("test"), + NewMatchRule("threadlocal"), + NewMatchRule("true"), + NewMatchRule("try"), + NewMatchRule("undefined"), + NewMatchRule("union"), + NewMatchRule("unreachable"), + NewMatchRule("usingnamespace"), + NewMatchRule("var"), + NewMatchRule("volatile"), + NewMatchRule("while"), + NewMatchRule("i8"), + NewMatchRule("u8"), + NewMatchRule("i16"), + NewMatchRule("u16"), + NewMatchRule("i32"), + NewMatchRule("u32"), + NewMatchRule("i64"), + NewMatchRule("u64"), + NewMatchRule("i128"), + NewMatchRule("u128"), + NewMatchRule("isize"), + NewMatchRule("usize"), + NewMatchRule("c_short"), + NewMatchRule("c_ushort"), + NewMatchRule("c_int"), + NewMatchRule("c_uint"), + NewMatchRule("c_long"), + NewMatchRule("c_ulong"), + NewMatchRule("c_longlong"), + NewMatchRule("c_ulonglong"), + NewMatchRule("c_longdouble"), + NewMatchRule("f16"), + NewMatchRule("f32"), + NewMatchRule("f64"), + NewMatchRule("f128"), + NewMatchRule("bool"), + NewMatchRule("anyopaque"), + NewMatchRule("void"), + NewMatchRule("noreturn"), + NewMatchRule("type"), + NewMatchRule("anyerror"), + NewMatchRule("comptime_int"), + NewMatchRule("comptime_float"), + NewMatchRegexRule("^[i|u][0-9]+$"), + }, + }, + } +} diff --git a/cmd/karmem/kmparser/kmgen.km b/cmd/karmem/kmparser/kmgen.km index aaf321b..c0459af 100644 --- a/cmd/karmem/kmparser/kmgen.km +++ b/cmd/karmem/kmparser/kmgen.km @@ -22,6 +22,42 @@ enum TypeFormat uint8 { Table; } +enum RuleType uint16 { + None; + ReservedName; + ReservedType; + DuplicateName; + DuplicateType; + CollisionName; + CollisionType; +} + +enum Language uint64 { + None = 0; + AssemblyScript = 1; + Zig = 2; + C = 4; + Swift = 8; + Dotnet = 16; + Odin = 32; + Golang = 64; + Rust = 128; + Nim = 256; + Kotlin = 512; + D = 1024; + Haskell = 2048; + Crystal = 4096; + Typescript = 8192; + PHP = 16384; + Python = 32768; +} + + +struct SchemaPosition table @id(`8944966152016866568`) { + File []char; + Line uint32; + Column uint32; +} struct Type table @id(`2206764383142231373`) { Schema []char; @@ -31,6 +67,17 @@ struct Type table @id(`2206764383142231373`) { Model TypeModel; } +struct WarningData table @id(`9648278712160971894`) { + Message []char; + Rule []char; + Type RuleType; + Languages Language; +} + +struct Warning inline @id(`5319256325625522744`) { + Data WarningData; +} + struct PaddingType inline @id(`6449815373135188035`) { Data Type; } @@ -55,9 +102,11 @@ struct StructFieldSize table @id(`3117293985139574571`) { } struct EnumFieldData table @id(`6917629752752470509`) { - Name []char; - Value []char; - Tags []Tag; + Name []char; + Value []char; + Tags []Tag; + Position SchemaPosition; + Warnings []Warning; } struct EnumField inline @id(`18350873289003309128`) { @@ -70,6 +119,8 @@ struct EnumData table @id(`18057555498029063613`) { Fields []EnumField; Tags []Tag; IsSequential bool; + Position SchemaPosition; + Warnings []Warning; } struct Enumeration inline @id(`1253319329451847685`) { @@ -77,11 +128,13 @@ struct Enumeration inline @id(`1253319329451847685`) { } struct StructFieldData table @id(`17962757807284521522`) { - Name []char; - Type Type; - Offset uint32; - Tags []Tag; - Size StructFieldSize; + Name []char; + Type Type; + Offset uint32; + Tags []Tag; + Size StructFieldSize; + Position SchemaPosition; + Warnings []Warning; } struct StructField inline @id(`12155838558451759529`) { @@ -89,13 +142,15 @@ struct StructField inline @id(`12155838558451759529`) { } struct StructData table @id(`8290009745541165076`) { - ID uint64; - Name []char; - Size StructSize; - Fields []StructField; - Class StructClass; - Tags []Tag; - Packed bool; + ID uint64; + Name []char; + Size StructSize; + Fields []StructField; + Class StructClass; + Tags []Tag; + Packed bool; + Position SchemaPosition; + Warnings []Warning; } struct Structure inline @id(`18088017590773436939`) { diff --git a/cmd/karmem/kmparser/kmparser_extension.go b/cmd/karmem/kmparser/kmparser_extension.go index 603cd75..5ed9b93 100644 --- a/cmd/karmem/kmparser/kmparser_extension.go +++ b/cmd/karmem/kmparser/kmparser_extension.go @@ -83,6 +83,6 @@ func (x *Type) IsEnum() bool { return x.Format == TypeFormatEnum } -func (x StructData) IsTable() bool { +func (x *StructData) IsTable() bool { return x.Class == StructClassTable } diff --git a/cmd/karmem/kmparser/kmparser_generated.go b/cmd/karmem/kmparser/kmparser_generated.go index be5329e..793b267 100644 --- a/cmd/karmem/kmparser/kmparser_generated.go +++ b/cmd/karmem/kmparser/kmparser_generated.go @@ -8,7 +8,7 @@ import ( var _ unsafe.Pointer -var _Null = [42]byte{} +var _Null = [54]byte{} var _NullReader = karmem.NewReader(_Null[:]) type ( @@ -45,12 +45,53 @@ const ( TypeFormatTable TypeFormat = 4 ) +type ( + RuleType uint16 +) + +const ( + RuleTypeNone RuleType = 0 + RuleTypeReservedName RuleType = 1 + RuleTypeReservedType RuleType = 2 + RuleTypeDuplicateName RuleType = 3 + RuleTypeDuplicateType RuleType = 4 + RuleTypeCollisionName RuleType = 5 + RuleTypeCollisionType RuleType = 6 +) + +type ( + Language uint64 +) + +const ( + LanguageNone Language = 0 + LanguageAssemblyScript Language = 1 + LanguageZig Language = 2 + LanguageC Language = 4 + LanguageSwift Language = 8 + LanguageDotnet Language = 16 + LanguageOdin Language = 32 + LanguageGolang Language = 64 + LanguageRust Language = 128 + LanguageNim Language = 256 + LanguageKotlin Language = 512 + LanguageD Language = 1024 + LanguageHaskell Language = 2048 + LanguageCrystal Language = 4096 + LanguageTypescript Language = 8192 + LanguagePHP Language = 16384 + LanguagePython Language = 32768 +) + type ( PacketIdentifier uint64 ) const ( + PacketIdentifierSchemaPosition = 8944966152016866568 PacketIdentifierType = 2206764383142231373 + PacketIdentifierWarningData = 9648278712160971894 + PacketIdentifierWarning = 5319256325625522744 PacketIdentifierPaddingType = 6449815373135188035 PacketIdentifierTag = 9280816983786621498 PacketIdentifierStructSize = 2296279785726396957 @@ -64,9 +105,74 @@ const ( PacketIdentifierStructData = 8290009745541165076 PacketIdentifierStructure = 18088017590773436939 PacketIdentifierContentSize = 8764462619562198222 + PacketIdentifierContentOptions = 12347233001904861813 PacketIdentifierContent = 6792576797909524956 ) +type SchemaPosition struct { + File string + Line uint32 + Column uint32 +} + +func NewSchemaPosition() SchemaPosition { + return SchemaPosition{} +} + +func (x *SchemaPosition) PacketIdentifier() PacketIdentifier { + return PacketIdentifierSchemaPosition +} + +func (x *SchemaPosition) Reset() { + x.Read((*SchemaPositionViewer)(unsafe.Pointer(&_Null[0])), _NullReader) +} + +func (x *SchemaPosition) WriteAsRoot(writer *karmem.Writer) (offset uint, err error) { + return x.Write(writer, 0) +} + +func (x *SchemaPosition) Write(writer *karmem.Writer, start uint) (offset uint, err error) { + offset = start + size := uint(20) + if offset == 0 { + offset, err = writer.Alloc(size) + if err != nil { + return 0, err + } + } + writer.Write4At(offset, uint32(20)) + __FileSize := uint(1 * len(x.File)) + __FileOffset, err := writer.Alloc(__FileSize) + if err != nil { + return 0, err + } + writer.Write4At(offset+4, uint32(__FileOffset)) + writer.Write4At(offset+4+4, uint32(__FileSize)) + __FileSlice := [3]uint{*(*uint)(unsafe.Pointer(&x.File)), __FileSize, __FileSize} + writer.WriteAt(__FileOffset, *(*[]byte)(unsafe.Pointer(&__FileSlice))) + __LineOffset := offset + 12 + writer.Write4At(__LineOffset, *(*uint32)(unsafe.Pointer(&x.Line))) + __ColumnOffset := offset + 16 + writer.Write4At(__ColumnOffset, *(*uint32)(unsafe.Pointer(&x.Column))) + + return offset, nil +} + +func (x *SchemaPosition) ReadAsRoot(reader *karmem.Reader) { + x.Read(NewSchemaPositionViewer(reader, 0), reader) +} + +func (x *SchemaPosition) Read(viewer *SchemaPositionViewer, reader *karmem.Reader) { + __FileString := viewer.File(reader) + if x.File != __FileString { + __FileStringCopy := make([]byte, len(__FileString)) + copy(__FileStringCopy, __FileString) + x.File = *(*string)(unsafe.Pointer(&__FileStringCopy)) + } + x.Line = viewer.Line() + x.Column = viewer.Column() +} + type Type struct { Schema string PlainSchema string @@ -151,6 +257,136 @@ func (x *Type) Read(viewer *TypeViewer, reader *karmem.Reader) { x.Model = TypeModel(viewer.Model()) } +type WarningData struct { + Message string + Rule string + Type RuleType + Languages Language +} + +func NewWarningData() WarningData { + return WarningData{} +} + +func (x *WarningData) PacketIdentifier() PacketIdentifier { + return PacketIdentifierWarningData +} + +func (x *WarningData) Reset() { + x.Read((*WarningDataViewer)(unsafe.Pointer(&_Null[0])), _NullReader) +} + +func (x *WarningData) WriteAsRoot(writer *karmem.Writer) (offset uint, err error) { + return x.Write(writer, 0) +} + +func (x *WarningData) Write(writer *karmem.Writer, start uint) (offset uint, err error) { + offset = start + size := uint(30) + if offset == 0 { + offset, err = writer.Alloc(size) + if err != nil { + return 0, err + } + } + writer.Write4At(offset, uint32(30)) + __MessageSize := uint(1 * len(x.Message)) + __MessageOffset, err := writer.Alloc(__MessageSize) + if err != nil { + return 0, err + } + writer.Write4At(offset+4, uint32(__MessageOffset)) + writer.Write4At(offset+4+4, uint32(__MessageSize)) + __MessageSlice := [3]uint{*(*uint)(unsafe.Pointer(&x.Message)), __MessageSize, __MessageSize} + writer.WriteAt(__MessageOffset, *(*[]byte)(unsafe.Pointer(&__MessageSlice))) + __RuleSize := uint(1 * len(x.Rule)) + __RuleOffset, err := writer.Alloc(__RuleSize) + if err != nil { + return 0, err + } + writer.Write4At(offset+12, uint32(__RuleOffset)) + writer.Write4At(offset+12+4, uint32(__RuleSize)) + __RuleSlice := [3]uint{*(*uint)(unsafe.Pointer(&x.Rule)), __RuleSize, __RuleSize} + writer.WriteAt(__RuleOffset, *(*[]byte)(unsafe.Pointer(&__RuleSlice))) + __TypeOffset := offset + 20 + writer.Write2At(__TypeOffset, *(*uint16)(unsafe.Pointer(&x.Type))) + __LanguagesOffset := offset + 22 + writer.Write8At(__LanguagesOffset, *(*uint64)(unsafe.Pointer(&x.Languages))) + + return offset, nil +} + +func (x *WarningData) ReadAsRoot(reader *karmem.Reader) { + x.Read(NewWarningDataViewer(reader, 0), reader) +} + +func (x *WarningData) Read(viewer *WarningDataViewer, reader *karmem.Reader) { + __MessageString := viewer.Message(reader) + if x.Message != __MessageString { + __MessageStringCopy := make([]byte, len(__MessageString)) + copy(__MessageStringCopy, __MessageString) + x.Message = *(*string)(unsafe.Pointer(&__MessageStringCopy)) + } + __RuleString := viewer.Rule(reader) + if x.Rule != __RuleString { + __RuleStringCopy := make([]byte, len(__RuleString)) + copy(__RuleStringCopy, __RuleString) + x.Rule = *(*string)(unsafe.Pointer(&__RuleStringCopy)) + } + x.Type = RuleType(viewer.Type()) + x.Languages = Language(viewer.Languages()) +} + +type Warning struct { + Data WarningData +} + +func NewWarning() Warning { + return Warning{} +} + +func (x *Warning) PacketIdentifier() PacketIdentifier { + return PacketIdentifierWarning +} + +func (x *Warning) Reset() { + x.Read((*WarningViewer)(unsafe.Pointer(&_Null[0])), _NullReader) +} + +func (x *Warning) WriteAsRoot(writer *karmem.Writer) (offset uint, err error) { + return x.Write(writer, 0) +} + +func (x *Warning) Write(writer *karmem.Writer, start uint) (offset uint, err error) { + offset = start + size := uint(4) + if offset == 0 { + offset, err = writer.Alloc(size) + if err != nil { + return 0, err + } + } + __DataSize := uint(30) + __DataOffset, err := writer.Alloc(__DataSize) + if err != nil { + return 0, err + } + writer.Write4At(offset+0, uint32(__DataOffset)) + if _, err := x.Data.Write(writer, __DataOffset); err != nil { + return offset, err + } + + return offset, nil +} + +func (x *Warning) ReadAsRoot(reader *karmem.Reader) { + x.Read(NewWarningViewer(reader, 0), reader) +} + +func (x *Warning) Read(viewer *WarningViewer, reader *karmem.Reader) { + x.Data.Read(viewer.Data(reader), reader) +} + type PaddingType struct { Data Type } @@ -407,9 +643,11 @@ func (x *StructFieldSize) Read(viewer *StructFieldSizeViewer, reader *karmem.Rea } type EnumFieldData struct { - Name string - Value string - Tags []Tag + Name string + Value string + Tags []Tag + Position SchemaPosition + Warnings []Warning } func NewEnumFieldData() EnumFieldData { @@ -430,14 +668,14 @@ func (x *EnumFieldData) WriteAsRoot(writer *karmem.Writer) (offset uint, err err func (x *EnumFieldData) Write(writer *karmem.Writer, start uint) (offset uint, err error) { offset = start - size := uint(28) + size := uint(40) if offset == 0 { offset, err = writer.Alloc(size) if err != nil { return 0, err } } - writer.Write4At(offset, uint32(28)) + writer.Write4At(offset, uint32(40)) __NameSize := uint(1 * len(x.Name)) __NameOffset, err := writer.Alloc(__NameSize) if err != nil { @@ -469,6 +707,28 @@ func (x *EnumFieldData) Write(writer *karmem.Writer, start uint) (offset uint, e } __TagsOffset += 16 } + __PositionSize := uint(20) + __PositionOffset, err := writer.Alloc(__PositionSize) + if err != nil { + return 0, err + } + writer.Write4At(offset+28, uint32(__PositionOffset)) + if _, err := x.Position.Write(writer, __PositionOffset); err != nil { + return offset, err + } + __WarningsSize := uint(4 * len(x.Warnings)) + __WarningsOffset, err := writer.Alloc(__WarningsSize) + if err != nil { + return 0, err + } + writer.Write4At(offset+32, uint32(__WarningsOffset)) + writer.Write4At(offset+32+4, uint32(__WarningsSize)) + for i := range x.Warnings { + if _, err := x.Warnings[i].Write(writer, __WarningsOffset); err != nil { + return offset, err + } + __WarningsOffset += 4 + } return offset, nil } @@ -502,6 +762,19 @@ func (x *EnumFieldData) Read(viewer *EnumFieldDataViewer, reader *karmem.Reader) x.Tags[i].Read(&__TagsSlice[i], reader) } x.Tags = x.Tags[:__TagsLen] + x.Position.Read(viewer.Position(reader), reader) + __WarningsSlice := viewer.Warnings(reader) + __WarningsLen := len(__WarningsSlice) + if __WarningsLen > cap(x.Warnings) { + x.Warnings = append(x.Warnings, make([]Warning, __WarningsLen-len(x.Warnings))...) + } + if __WarningsLen > len(x.Warnings) { + x.Warnings = x.Warnings[:__WarningsLen] + } + for i := 0; i < __WarningsLen; i++ { + x.Warnings[i].Read(&__WarningsSlice[i], reader) + } + x.Warnings = x.Warnings[:__WarningsLen] } type EnumField struct { @@ -533,7 +806,7 @@ func (x *EnumField) Write(writer *karmem.Writer, start uint) (offset uint, err e return 0, err } } - __DataSize := uint(28) + __DataSize := uint(40) __DataOffset, err := writer.Alloc(__DataSize) if err != nil { return 0, err @@ -560,6 +833,8 @@ type EnumData struct { Fields []EnumField Tags []Tag IsSequential bool + Position SchemaPosition + Warnings []Warning } func NewEnumData() EnumData { @@ -580,14 +855,14 @@ func (x *EnumData) WriteAsRoot(writer *karmem.Writer) (offset uint, err error) { func (x *EnumData) Write(writer *karmem.Writer, start uint) (offset uint, err error) { offset = start - size := uint(33) + size := uint(45) if offset == 0 { offset, err = writer.Alloc(size) if err != nil { return 0, err } } - writer.Write4At(offset, uint32(33)) + writer.Write4At(offset, uint32(45)) __NameSize := uint(1 * len(x.Name)) __NameOffset, err := writer.Alloc(__NameSize) if err != nil { @@ -634,6 +909,28 @@ func (x *EnumData) Write(writer *karmem.Writer, start uint) (offset uint, err er } __IsSequentialOffset := offset + 32 writer.Write1At(__IsSequentialOffset, *(*uint8)(unsafe.Pointer(&x.IsSequential))) + __PositionSize := uint(20) + __PositionOffset, err := writer.Alloc(__PositionSize) + if err != nil { + return 0, err + } + writer.Write4At(offset+33, uint32(__PositionOffset)) + if _, err := x.Position.Write(writer, __PositionOffset); err != nil { + return offset, err + } + __WarningsSize := uint(4 * len(x.Warnings)) + __WarningsOffset, err := writer.Alloc(__WarningsSize) + if err != nil { + return 0, err + } + writer.Write4At(offset+37, uint32(__WarningsOffset)) + writer.Write4At(offset+37+4, uint32(__WarningsSize)) + for i := range x.Warnings { + if _, err := x.Warnings[i].Write(writer, __WarningsOffset); err != nil { + return offset, err + } + __WarningsOffset += 4 + } return offset, nil } @@ -675,6 +972,19 @@ func (x *EnumData) Read(viewer *EnumDataViewer, reader *karmem.Reader) { } x.Tags = x.Tags[:__TagsLen] x.IsSequential = viewer.IsSequential() + x.Position.Read(viewer.Position(reader), reader) + __WarningsSlice := viewer.Warnings(reader) + __WarningsLen := len(__WarningsSlice) + if __WarningsLen > cap(x.Warnings) { + x.Warnings = append(x.Warnings, make([]Warning, __WarningsLen-len(x.Warnings))...) + } + if __WarningsLen > len(x.Warnings) { + x.Warnings = x.Warnings[:__WarningsLen] + } + for i := 0; i < __WarningsLen; i++ { + x.Warnings[i].Read(&__WarningsSlice[i], reader) + } + x.Warnings = x.Warnings[:__WarningsLen] } type Enumeration struct { @@ -706,7 +1016,7 @@ func (x *Enumeration) Write(writer *karmem.Writer, start uint) (offset uint, err return 0, err } } - __DataSize := uint(33) + __DataSize := uint(45) __DataOffset, err := writer.Alloc(__DataSize) if err != nil { return 0, err @@ -728,11 +1038,13 @@ func (x *Enumeration) Read(viewer *EnumerationViewer, reader *karmem.Reader) { } type StructFieldData struct { - Name string - Type Type - Offset uint32 - Tags []Tag - Size StructFieldSize + Name string + Type Type + Offset uint32 + Tags []Tag + Size StructFieldSize + Position SchemaPosition + Warnings []Warning } func NewStructFieldData() StructFieldData { @@ -753,14 +1065,14 @@ func (x *StructFieldData) WriteAsRoot(writer *karmem.Writer) (offset uint, err e func (x *StructFieldData) Write(writer *karmem.Writer, start uint) (offset uint, err error) { offset = start - size := uint(32) + size := uint(44) if offset == 0 { offset, err = writer.Alloc(size) if err != nil { return 0, err } } - writer.Write4At(offset, uint32(32)) + writer.Write4At(offset, uint32(44)) __NameSize := uint(1 * len(x.Name)) __NameOffset, err := writer.Alloc(__NameSize) if err != nil { @@ -803,6 +1115,28 @@ func (x *StructFieldData) Write(writer *karmem.Writer, start uint) (offset uint, if _, err := x.Size.Write(writer, __SizeOffset); err != nil { return offset, err } + __PositionSize := uint(20) + __PositionOffset, err := writer.Alloc(__PositionSize) + if err != nil { + return 0, err + } + writer.Write4At(offset+32, uint32(__PositionOffset)) + if _, err := x.Position.Write(writer, __PositionOffset); err != nil { + return offset, err + } + __WarningsSize := uint(4 * len(x.Warnings)) + __WarningsOffset, err := writer.Alloc(__WarningsSize) + if err != nil { + return 0, err + } + writer.Write4At(offset+36, uint32(__WarningsOffset)) + writer.Write4At(offset+36+4, uint32(__WarningsSize)) + for i := range x.Warnings { + if _, err := x.Warnings[i].Write(writer, __WarningsOffset); err != nil { + return offset, err + } + __WarningsOffset += 4 + } return offset, nil } @@ -833,6 +1167,19 @@ func (x *StructFieldData) Read(viewer *StructFieldDataViewer, reader *karmem.Rea } x.Tags = x.Tags[:__TagsLen] x.Size.Read(viewer.Size(reader), reader) + x.Position.Read(viewer.Position(reader), reader) + __WarningsSlice := viewer.Warnings(reader) + __WarningsLen := len(__WarningsSlice) + if __WarningsLen > cap(x.Warnings) { + x.Warnings = append(x.Warnings, make([]Warning, __WarningsLen-len(x.Warnings))...) + } + if __WarningsLen > len(x.Warnings) { + x.Warnings = x.Warnings[:__WarningsLen] + } + for i := 0; i < __WarningsLen; i++ { + x.Warnings[i].Read(&__WarningsSlice[i], reader) + } + x.Warnings = x.Warnings[:__WarningsLen] } type StructField struct { @@ -864,7 +1211,7 @@ func (x *StructField) Write(writer *karmem.Writer, start uint) (offset uint, err return 0, err } } - __DataSize := uint(32) + __DataSize := uint(44) __DataOffset, err := writer.Alloc(__DataSize) if err != nil { return 0, err @@ -886,13 +1233,15 @@ func (x *StructField) Read(viewer *StructFieldViewer, reader *karmem.Reader) { } type StructData struct { - ID uint64 - Name string - Size StructSize - Fields []StructField - Class StructClass - Tags []Tag - Packed bool + ID uint64 + Name string + Size StructSize + Fields []StructField + Class StructClass + Tags []Tag + Packed bool + Position SchemaPosition + Warnings []Warning } func NewStructData() StructData { @@ -913,14 +1262,14 @@ func (x *StructData) WriteAsRoot(writer *karmem.Writer) (offset uint, err error) func (x *StructData) Write(writer *karmem.Writer, start uint) (offset uint, err error) { offset = start - size := uint(42) + size := uint(54) if offset == 0 { offset, err = writer.Alloc(size) if err != nil { return 0, err } } - writer.Write4At(offset, uint32(42)) + writer.Write4At(offset, uint32(54)) __IDOffset := offset + 4 writer.Write8At(__IDOffset, *(*uint64)(unsafe.Pointer(&x.ID))) __NameSize := uint(1 * len(x.Name)) @@ -971,6 +1320,28 @@ func (x *StructData) Write(writer *karmem.Writer, start uint) (offset uint, err } __PackedOffset := offset + 41 writer.Write1At(__PackedOffset, *(*uint8)(unsafe.Pointer(&x.Packed))) + __PositionSize := uint(20) + __PositionOffset, err := writer.Alloc(__PositionSize) + if err != nil { + return 0, err + } + writer.Write4At(offset+42, uint32(__PositionOffset)) + if _, err := x.Position.Write(writer, __PositionOffset); err != nil { + return offset, err + } + __WarningsSize := uint(4 * len(x.Warnings)) + __WarningsOffset, err := writer.Alloc(__WarningsSize) + if err != nil { + return 0, err + } + writer.Write4At(offset+46, uint32(__WarningsOffset)) + writer.Write4At(offset+46+4, uint32(__WarningsSize)) + for i := range x.Warnings { + if _, err := x.Warnings[i].Write(writer, __WarningsOffset); err != nil { + return offset, err + } + __WarningsOffset += 4 + } return offset, nil } @@ -1014,6 +1385,19 @@ func (x *StructData) Read(viewer *StructDataViewer, reader *karmem.Reader) { } x.Tags = x.Tags[:__TagsLen] x.Packed = viewer.Packed() + x.Position.Read(viewer.Position(reader), reader) + __WarningsSlice := viewer.Warnings(reader) + __WarningsLen := len(__WarningsSlice) + if __WarningsLen > cap(x.Warnings) { + x.Warnings = append(x.Warnings, make([]Warning, __WarningsLen-len(x.Warnings))...) + } + if __WarningsLen > len(x.Warnings) { + x.Warnings = x.Warnings[:__WarningsLen] + } + for i := 0; i < __WarningsLen; i++ { + x.Warnings[i].Read(&__WarningsSlice[i], reader) + } + x.Warnings = x.Warnings[:__WarningsLen] } type Structure struct { @@ -1045,7 +1429,7 @@ func (x *Structure) Write(writer *karmem.Writer, start uint) (offset uint, err e return 0, err } } - __DataSize := uint(42) + __DataSize := uint(54) __DataOffset, err := writer.Alloc(__DataSize) if err != nil { return 0, err @@ -1110,6 +1494,94 @@ func (x *ContentSize) Read(viewer *ContentSizeViewer, reader *karmem.Reader) { x.Largest = viewer.Largest() } +type ContentOptions struct { + Module string + Import string + Prefix string +} + +func NewContentOptions() ContentOptions { + return ContentOptions{} +} + +func (x *ContentOptions) PacketIdentifier() PacketIdentifier { + return PacketIdentifierContentOptions +} + +func (x *ContentOptions) Reset() { + x.Read((*ContentOptionsViewer)(unsafe.Pointer(&_Null[0])), _NullReader) +} + +func (x *ContentOptions) WriteAsRoot(writer *karmem.Writer) (offset uint, err error) { + return x.Write(writer, 0) +} + +func (x *ContentOptions) Write(writer *karmem.Writer, start uint) (offset uint, err error) { + offset = start + size := uint(28) + if offset == 0 { + offset, err = writer.Alloc(size) + if err != nil { + return 0, err + } + } + writer.Write4At(offset, uint32(28)) + __ModuleSize := uint(1 * len(x.Module)) + __ModuleOffset, err := writer.Alloc(__ModuleSize) + if err != nil { + return 0, err + } + writer.Write4At(offset+4, uint32(__ModuleOffset)) + writer.Write4At(offset+4+4, uint32(__ModuleSize)) + __ModuleSlice := [3]uint{*(*uint)(unsafe.Pointer(&x.Module)), __ModuleSize, __ModuleSize} + writer.WriteAt(__ModuleOffset, *(*[]byte)(unsafe.Pointer(&__ModuleSlice))) + __ImportSize := uint(1 * len(x.Import)) + __ImportOffset, err := writer.Alloc(__ImportSize) + if err != nil { + return 0, err + } + writer.Write4At(offset+12, uint32(__ImportOffset)) + writer.Write4At(offset+12+4, uint32(__ImportSize)) + __ImportSlice := [3]uint{*(*uint)(unsafe.Pointer(&x.Import)), __ImportSize, __ImportSize} + writer.WriteAt(__ImportOffset, *(*[]byte)(unsafe.Pointer(&__ImportSlice))) + __PrefixSize := uint(1 * len(x.Prefix)) + __PrefixOffset, err := writer.Alloc(__PrefixSize) + if err != nil { + return 0, err + } + writer.Write4At(offset+20, uint32(__PrefixOffset)) + writer.Write4At(offset+20+4, uint32(__PrefixSize)) + __PrefixSlice := [3]uint{*(*uint)(unsafe.Pointer(&x.Prefix)), __PrefixSize, __PrefixSize} + writer.WriteAt(__PrefixOffset, *(*[]byte)(unsafe.Pointer(&__PrefixSlice))) + + return offset, nil +} + +func (x *ContentOptions) ReadAsRoot(reader *karmem.Reader) { + x.Read(NewContentOptionsViewer(reader, 0), reader) +} + +func (x *ContentOptions) Read(viewer *ContentOptionsViewer, reader *karmem.Reader) { + __ModuleString := viewer.Module(reader) + if x.Module != __ModuleString { + __ModuleStringCopy := make([]byte, len(__ModuleString)) + copy(__ModuleStringCopy, __ModuleString) + x.Module = *(*string)(unsafe.Pointer(&__ModuleStringCopy)) + } + __ImportString := viewer.Import(reader) + if x.Import != __ImportString { + __ImportStringCopy := make([]byte, len(__ImportString)) + copy(__ImportStringCopy, __ImportString) + x.Import = *(*string)(unsafe.Pointer(&__ImportStringCopy)) + } + __PrefixString := viewer.Prefix(reader) + if x.Prefix != __PrefixString { + __PrefixStringCopy := make([]byte, len(__PrefixString)) + copy(__PrefixStringCopy, __PrefixString) + x.Prefix = *(*string)(unsafe.Pointer(&__PrefixStringCopy)) + } +} + type Content struct { Tags []Tag Structs []Structure @@ -1259,6 +1731,50 @@ func (x *Content) Read(viewer *ContentViewer, reader *karmem.Reader) { x.Packed = viewer.Packed() } +type SchemaPositionViewer [20]byte + +func NewSchemaPositionViewer(reader *karmem.Reader, offset uint32) (v *SchemaPositionViewer) { + if !reader.IsValidOffset(offset, 4) { + return (*SchemaPositionViewer)(unsafe.Pointer(&_Null[0])) + } + v = (*SchemaPositionViewer)(unsafe.Add(reader.Pointer, offset)) + if !reader.IsValidOffset(offset, v.size()) { + return (*SchemaPositionViewer)(unsafe.Pointer(&_Null[0])) + } + return v +} + +func (x *SchemaPositionViewer) size() uint32 { + return *(*uint32)(unsafe.Pointer(x)) +} +func (x *SchemaPositionViewer) File(reader *karmem.Reader) (v string) { + if 4+8 > x.size() { + return v + } + offset := *(*uint32)(unsafe.Add(unsafe.Pointer(x), 4)) + size := *(*uint32)(unsafe.Add(unsafe.Pointer(x), 4+4)) + if !reader.IsValidOffset(offset, size) { + return "" + } + length := uintptr(size / 1) + slice := [3]uintptr{ + uintptr(unsafe.Add(reader.Pointer, offset)), length, length, + } + return *(*string)(unsafe.Pointer(&slice)) +} +func (x *SchemaPositionViewer) Line() (v uint32) { + if 12+4 > x.size() { + return v + } + return *(*uint32)(unsafe.Add(unsafe.Pointer(x), 12)) +} +func (x *SchemaPositionViewer) Column() (v uint32) { + if 16+4 > x.size() { + return v + } + return *(*uint32)(unsafe.Add(unsafe.Pointer(x), 16)) +} + type TypeViewer [26]byte func NewTypeViewer(reader *karmem.Reader, offset uint32) (v *TypeViewer) { @@ -1324,6 +1840,83 @@ func (x *TypeViewer) Model() (v TypeModel) { return *(*TypeModel)(unsafe.Add(unsafe.Pointer(x), 25)) } +type WarningDataViewer [30]byte + +func NewWarningDataViewer(reader *karmem.Reader, offset uint32) (v *WarningDataViewer) { + if !reader.IsValidOffset(offset, 4) { + return (*WarningDataViewer)(unsafe.Pointer(&_Null[0])) + } + v = (*WarningDataViewer)(unsafe.Add(reader.Pointer, offset)) + if !reader.IsValidOffset(offset, v.size()) { + return (*WarningDataViewer)(unsafe.Pointer(&_Null[0])) + } + return v +} + +func (x *WarningDataViewer) size() uint32 { + return *(*uint32)(unsafe.Pointer(x)) +} +func (x *WarningDataViewer) Message(reader *karmem.Reader) (v string) { + if 4+8 > x.size() { + return v + } + offset := *(*uint32)(unsafe.Add(unsafe.Pointer(x), 4)) + size := *(*uint32)(unsafe.Add(unsafe.Pointer(x), 4+4)) + if !reader.IsValidOffset(offset, size) { + return "" + } + length := uintptr(size / 1) + slice := [3]uintptr{ + uintptr(unsafe.Add(reader.Pointer, offset)), length, length, + } + return *(*string)(unsafe.Pointer(&slice)) +} +func (x *WarningDataViewer) Rule(reader *karmem.Reader) (v string) { + if 12+8 > x.size() { + return v + } + offset := *(*uint32)(unsafe.Add(unsafe.Pointer(x), 12)) + size := *(*uint32)(unsafe.Add(unsafe.Pointer(x), 12+4)) + if !reader.IsValidOffset(offset, size) { + return "" + } + length := uintptr(size / 1) + slice := [3]uintptr{ + uintptr(unsafe.Add(reader.Pointer, offset)), length, length, + } + return *(*string)(unsafe.Pointer(&slice)) +} +func (x *WarningDataViewer) Type() (v RuleType) { + if 20+2 > x.size() { + return v + } + return *(*RuleType)(unsafe.Add(unsafe.Pointer(x), 20)) +} +func (x *WarningDataViewer) Languages() (v Language) { + if 22+8 > x.size() { + return v + } + return *(*Language)(unsafe.Add(unsafe.Pointer(x), 22)) +} + +type WarningViewer [4]byte + +func NewWarningViewer(reader *karmem.Reader, offset uint32) (v *WarningViewer) { + if !reader.IsValidOffset(offset, 4) { + return (*WarningViewer)(unsafe.Pointer(&_Null[0])) + } + v = (*WarningViewer)(unsafe.Add(reader.Pointer, offset)) + return v +} + +func (x *WarningViewer) size() uint32 { + return 4 +} +func (x *WarningViewer) Data(reader *karmem.Reader) (v *WarningDataViewer) { + offset := *(*uint32)(unsafe.Add(unsafe.Pointer(x), 0)) + return NewWarningDataViewer(reader, offset) +} + type PaddingTypeViewer [4]byte func NewPaddingTypeViewer(reader *karmem.Reader, offset uint32) (v *PaddingTypeViewer) { @@ -1471,7 +2064,7 @@ func (x *StructFieldSizeViewer) Field() (v uint32) { return *(*uint32)(unsafe.Add(unsafe.Pointer(x), 12)) } -type EnumFieldDataViewer [28]byte +type EnumFieldDataViewer [40]byte func NewEnumFieldDataViewer(reader *karmem.Reader, offset uint32) (v *EnumFieldDataViewer) { if !reader.IsValidOffset(offset, 4) { @@ -1532,6 +2125,28 @@ func (x *EnumFieldDataViewer) Tags(reader *karmem.Reader) (v []TagViewer) { } return *(*[]TagViewer)(unsafe.Pointer(&slice)) } +func (x *EnumFieldDataViewer) Position(reader *karmem.Reader) (v *SchemaPositionViewer) { + if 28+4 > x.size() { + return (*SchemaPositionViewer)(unsafe.Pointer(&_Null[0])) + } + offset := *(*uint32)(unsafe.Add(unsafe.Pointer(x), 28)) + return NewSchemaPositionViewer(reader, offset) +} +func (x *EnumFieldDataViewer) Warnings(reader *karmem.Reader) (v []WarningViewer) { + if 32+8 > x.size() { + return []WarningViewer{} + } + offset := *(*uint32)(unsafe.Add(unsafe.Pointer(x), 32)) + size := *(*uint32)(unsafe.Add(unsafe.Pointer(x), 32+4)) + if !reader.IsValidOffset(offset, size) { + return []WarningViewer{} + } + length := uintptr(size / 4) + slice := [3]uintptr{ + uintptr(unsafe.Add(reader.Pointer, offset)), length, length, + } + return *(*[]WarningViewer)(unsafe.Pointer(&slice)) +} type EnumFieldViewer [4]byte @@ -1551,7 +2166,7 @@ func (x *EnumFieldViewer) Data(reader *karmem.Reader) (v *EnumFieldDataViewer) { return NewEnumFieldDataViewer(reader, offset) } -type EnumDataViewer [33]byte +type EnumDataViewer [45]byte func NewEnumDataViewer(reader *karmem.Reader, offset uint32) (v *EnumDataViewer) { if !reader.IsValidOffset(offset, 4) { @@ -1625,6 +2240,28 @@ func (x *EnumDataViewer) IsSequential() (v bool) { } return *(*bool)(unsafe.Add(unsafe.Pointer(x), 32)) } +func (x *EnumDataViewer) Position(reader *karmem.Reader) (v *SchemaPositionViewer) { + if 33+4 > x.size() { + return (*SchemaPositionViewer)(unsafe.Pointer(&_Null[0])) + } + offset := *(*uint32)(unsafe.Add(unsafe.Pointer(x), 33)) + return NewSchemaPositionViewer(reader, offset) +} +func (x *EnumDataViewer) Warnings(reader *karmem.Reader) (v []WarningViewer) { + if 37+8 > x.size() { + return []WarningViewer{} + } + offset := *(*uint32)(unsafe.Add(unsafe.Pointer(x), 37)) + size := *(*uint32)(unsafe.Add(unsafe.Pointer(x), 37+4)) + if !reader.IsValidOffset(offset, size) { + return []WarningViewer{} + } + length := uintptr(size / 4) + slice := [3]uintptr{ + uintptr(unsafe.Add(reader.Pointer, offset)), length, length, + } + return *(*[]WarningViewer)(unsafe.Pointer(&slice)) +} type EnumerationViewer [4]byte @@ -1644,7 +2281,7 @@ func (x *EnumerationViewer) Data(reader *karmem.Reader) (v *EnumDataViewer) { return NewEnumDataViewer(reader, offset) } -type StructFieldDataViewer [32]byte +type StructFieldDataViewer [44]byte func NewStructFieldDataViewer(reader *karmem.Reader, offset uint32) (v *StructFieldDataViewer) { if !reader.IsValidOffset(offset, 4) { @@ -1710,6 +2347,28 @@ func (x *StructFieldDataViewer) Size(reader *karmem.Reader) (v *StructFieldSizeV offset := *(*uint32)(unsafe.Add(unsafe.Pointer(x), 28)) return NewStructFieldSizeViewer(reader, offset) } +func (x *StructFieldDataViewer) Position(reader *karmem.Reader) (v *SchemaPositionViewer) { + if 32+4 > x.size() { + return (*SchemaPositionViewer)(unsafe.Pointer(&_Null[0])) + } + offset := *(*uint32)(unsafe.Add(unsafe.Pointer(x), 32)) + return NewSchemaPositionViewer(reader, offset) +} +func (x *StructFieldDataViewer) Warnings(reader *karmem.Reader) (v []WarningViewer) { + if 36+8 > x.size() { + return []WarningViewer{} + } + offset := *(*uint32)(unsafe.Add(unsafe.Pointer(x), 36)) + size := *(*uint32)(unsafe.Add(unsafe.Pointer(x), 36+4)) + if !reader.IsValidOffset(offset, size) { + return []WarningViewer{} + } + length := uintptr(size / 4) + slice := [3]uintptr{ + uintptr(unsafe.Add(reader.Pointer, offset)), length, length, + } + return *(*[]WarningViewer)(unsafe.Pointer(&slice)) +} type StructFieldViewer [4]byte @@ -1729,7 +2388,7 @@ func (x *StructFieldViewer) Data(reader *karmem.Reader) (v *StructFieldDataViewe return NewStructFieldDataViewer(reader, offset) } -type StructDataViewer [42]byte +type StructDataViewer [54]byte func NewStructDataViewer(reader *karmem.Reader, offset uint32) (v *StructDataViewer) { if !reader.IsValidOffset(offset, 4) { @@ -1815,6 +2474,28 @@ func (x *StructDataViewer) Packed() (v bool) { } return *(*bool)(unsafe.Add(unsafe.Pointer(x), 41)) } +func (x *StructDataViewer) Position(reader *karmem.Reader) (v *SchemaPositionViewer) { + if 42+4 > x.size() { + return (*SchemaPositionViewer)(unsafe.Pointer(&_Null[0])) + } + offset := *(*uint32)(unsafe.Add(unsafe.Pointer(x), 42)) + return NewSchemaPositionViewer(reader, offset) +} +func (x *StructDataViewer) Warnings(reader *karmem.Reader) (v []WarningViewer) { + if 46+8 > x.size() { + return []WarningViewer{} + } + offset := *(*uint32)(unsafe.Add(unsafe.Pointer(x), 46)) + size := *(*uint32)(unsafe.Add(unsafe.Pointer(x), 46+4)) + if !reader.IsValidOffset(offset, size) { + return []WarningViewer{} + } + length := uintptr(size / 4) + slice := [3]uintptr{ + uintptr(unsafe.Add(reader.Pointer, offset)), length, length, + } + return *(*[]WarningViewer)(unsafe.Pointer(&slice)) +} type StructureViewer [4]byte @@ -1857,6 +2538,68 @@ func (x *ContentSizeViewer) Largest() (v uint32) { return *(*uint32)(unsafe.Add(unsafe.Pointer(x), 4)) } +type ContentOptionsViewer [28]byte + +func NewContentOptionsViewer(reader *karmem.Reader, offset uint32) (v *ContentOptionsViewer) { + if !reader.IsValidOffset(offset, 4) { + return (*ContentOptionsViewer)(unsafe.Pointer(&_Null[0])) + } + v = (*ContentOptionsViewer)(unsafe.Add(reader.Pointer, offset)) + if !reader.IsValidOffset(offset, v.size()) { + return (*ContentOptionsViewer)(unsafe.Pointer(&_Null[0])) + } + return v +} + +func (x *ContentOptionsViewer) size() uint32 { + return *(*uint32)(unsafe.Pointer(x)) +} +func (x *ContentOptionsViewer) Module(reader *karmem.Reader) (v string) { + if 4+8 > x.size() { + return v + } + offset := *(*uint32)(unsafe.Add(unsafe.Pointer(x), 4)) + size := *(*uint32)(unsafe.Add(unsafe.Pointer(x), 4+4)) + if !reader.IsValidOffset(offset, size) { + return "" + } + length := uintptr(size / 1) + slice := [3]uintptr{ + uintptr(unsafe.Add(reader.Pointer, offset)), length, length, + } + return *(*string)(unsafe.Pointer(&slice)) +} +func (x *ContentOptionsViewer) Import(reader *karmem.Reader) (v string) { + if 12+8 > x.size() { + return v + } + offset := *(*uint32)(unsafe.Add(unsafe.Pointer(x), 12)) + size := *(*uint32)(unsafe.Add(unsafe.Pointer(x), 12+4)) + if !reader.IsValidOffset(offset, size) { + return "" + } + length := uintptr(size / 1) + slice := [3]uintptr{ + uintptr(unsafe.Add(reader.Pointer, offset)), length, length, + } + return *(*string)(unsafe.Pointer(&slice)) +} +func (x *ContentOptionsViewer) Prefix(reader *karmem.Reader) (v string) { + if 20+8 > x.size() { + return v + } + offset := *(*uint32)(unsafe.Add(unsafe.Pointer(x), 20)) + size := *(*uint32)(unsafe.Add(unsafe.Pointer(x), 20+4)) + if !reader.IsValidOffset(offset, size) { + return "" + } + length := uintptr(size / 1) + slice := [3]uintptr{ + uintptr(unsafe.Add(reader.Pointer, offset)), length, length, + } + return *(*string)(unsafe.Pointer(&slice)) +} + type ContentViewer [41]byte func NewContentViewer(reader *karmem.Reader, offset uint32) (v *ContentViewer) { diff --git a/cmd/karmem/kmparser/parser.go b/cmd/karmem/kmparser/parser.go index a812b75..cddefc4 100644 --- a/cmd/karmem/kmparser/parser.go +++ b/cmd/karmem/kmparser/parser.go @@ -15,11 +15,13 @@ import ( ) //go:generate go run ../main.go build -golang kmgen.km -//go:generate go run ../main.go fmt -s kmgen.km +//go:generate go run ../main.go fmt -w kmgen.km // Reader reads and decodes Karmem files. type Reader struct { - Parsed Content + Parsed Content + WarningsDisabled bool + hasher func(s string) uint64 hasherHash hash.Hash hasherKey []byte @@ -225,6 +227,10 @@ func unicodeSpaceTab(r rune) bool { func (r *Reader) enumName() parserFunc { b := r.nextRune() t := &r.Parsed.Enums[len(r.Parsed.Enums)-1].Data + t.Position.File = r.path + t.Position.Line = uint32(r.line) + t.Position.Column = uint32(r.column) + switch { case unicodeSpaceTab(b) && len(t.Name) > 0: return r.skipSpace(r.enumType) @@ -277,6 +283,10 @@ func (r *Reader) enumFieldName() parserFunc { b := r.nextRune() t := &r.Parsed.Enums[len(r.Parsed.Enums)-1].Data f := &t.Fields[len(t.Fields)-1].Data + f.Position.File = r.path + f.Position.Line = uint32(r.line) + f.Position.Column = uint32(r.column) + switch { case b == ';': r.prevRune() @@ -452,6 +462,9 @@ func (r *Reader) structInit() parserFunc { func (r *Reader) structName() parserFunc { b := r.nextRune() t := &r.Parsed.Structs[len(r.Parsed.Structs)-1].Data + t.Position.File = r.path + t.Position.Line = uint32(r.line) + t.Position.Column = uint32(r.column) switch { case unicodeSpaceTab(b) && len(t.Name) > 0: @@ -547,6 +560,9 @@ func (r *Reader) structFieldName() parserFunc { b := r.nextRune() t := &r.Parsed.Structs[len(r.Parsed.Structs)-1].Data f := &t.Fields[len(t.Fields)-1].Data + f.Position.File = r.path + f.Position.Line = uint32(r.line) + f.Position.Column = uint32(r.column) switch { case unicode.IsSpace(b) && len(f.Name) == 0: diff --git a/cmd/karmem/main.go b/cmd/karmem/main.go index 60720ed..920daf1 100644 --- a/cmd/karmem/main.go +++ b/cmd/karmem/main.go @@ -5,9 +5,11 @@ import ( "errors" "flag" "fmt" + "io" "os" "path/filepath" + "karmem.org/cmd/karmem/kmcheck" "karmem.org/cmd/karmem/kmgen" "karmem.org/cmd/karmem/kmparser" ) @@ -22,8 +24,11 @@ func main() { fmt.Println("Usage: karmem []") fmt.Println("Commands:") fmt.Println(" build") - fmt.Println(" Builds the schema file.") + fmt.Println(" Generates the language-specific implementation based on the schema file.") fmt.Println(" Use \"build help\" to see the list of available options.") + fmt.Println(" fmt") + fmt.Println(" Format the schema file.") + fmt.Println(" Use \"fmt help\" to see the list of available options.") os.Exit(1) } flag.Parse() @@ -94,6 +99,7 @@ type Build struct { SchemaFile language []bool output string + warns io.Writer generator []kmgen.Generator } @@ -103,9 +109,14 @@ func NewBuild() (b *Build, _ error) { b.language = make([]bool, len(kmgen.Generators)) for i, g := range kmgen.Generators { - flags.BoolVar(&b.language[i], g.Language(), false, fmt.Sprintf("Enable geneartion for %s language.", g.Language())) + flags.BoolVar(&b.language[i], g.Language(), false, fmt.Sprintf("Enable generation for %s language.", g.Language())) } flags.StringVar(&b.output, "o", ".", "Output directory path.") + var disableWarnings bool + flags.BoolVar(&disableWarnings, "s", false, "Silence warnings.") + if !disableWarnings { + b.warns = os.Stdout + } if err := flags.Parse(flag.Args()[1:]); err != nil { return nil, err } @@ -136,6 +147,11 @@ func (b *Build) Execute() error { return err } + if b.warns != nil { + kmcheck.Check(parsed) + ReportWarnings(b.warns, parsed) + } + for _, gen := range b.generator { compiler, err := gen.Start(parsed) if err != nil { @@ -185,7 +201,12 @@ func NewFormat() (f *Format, _ error) { flags := flag.NewFlagSet("build", flag.ExitOnError) f.language = make([]bool, len(kmgen.Generators)) - flags.BoolVar(&f.save, "s", false, "Save and override the original schema file.") + flags.BoolVar(&f.save, "w", false, "Write and override the original schema file.") + var disableWarnings bool + flags.BoolVar(&disableWarnings, "s", false, "Silence warnings.") + if !disableWarnings { + f.warns = os.Stdout + } if err := flags.Parse(flag.Args()[1:]); err != nil { return nil, err } @@ -206,6 +227,11 @@ func (b *Format) Execute() error { return err } + if b.warns != nil { + kmcheck.Check(parsed) + ReportWarnings(b.warns, parsed) + } + gen := kmgen.KarmemSchemaGenerator() compiler, err := gen.Start(parsed) if err != nil { @@ -239,3 +265,30 @@ func (b *Format) Execute() error { } return nil } + +func ReportWarnings(out io.Writer, parsed *kmparser.Content) { + for _, x := range parsed.Structs { + for _, w := range x.Data.Warnings { + reportWarning(out, &x.Data.Position, &w.Data) + } + for _, x := range x.Data.Fields { + for _, w := range x.Data.Warnings { + reportWarning(out, &x.Data.Position, &w.Data) + } + } + } + for _, x := range parsed.Enums { + for _, w := range x.Data.Warnings { + reportWarning(out, &x.Data.Position, &w.Data) + } + for _, x := range x.Data.Fields { + for _, w := range x.Data.Warnings { + reportWarning(out, &x.Data.Position, &w.Data) + } + } + } +} + +func reportWarning(out io.Writer, position *kmparser.SchemaPosition, w *kmparser.WarningData) { + fmt.Fprintf(out, "Warning: %s:%d:%d %s\n", position.File, position.Line, position.Column, w.Message) +}