diff --git a/Makefile b/Makefile index 692b35514d..a7050ac189 100644 --- a/Makefile +++ b/Makefile @@ -26,3 +26,10 @@ psql: mysqlsh: mysqlsh --sql --user root --password mysecretpassword --database dinotest 127.0.0.1:3306 + + +# $ protoc --version +# libprotoc 3.17.3 +# go install google.golang.org/protobuf/cmd/protoc-gen-go@latest +proto: + protoc -I ./protos --go_out=. --go_opt=module=github.com/kyleconroy/sqlc ./protos/**/*.proto diff --git a/examples/python/src/authors/models.py b/examples/python/src/authors/models.py index 42d945abe1..9cac9b2798 100644 --- a/examples/python/src/authors/models.py +++ b/examples/python/src/authors/models.py @@ -1,9 +1,6 @@ # Code generated by sqlc. DO NOT EDIT. -from typing import Optional - import dataclasses - - +from typing import Optional @dataclasses.dataclass() @@ -11,5 +8,3 @@ class Author: id: int name: str bio: Optional[str] - - diff --git a/examples/python/src/booktest/models.py b/examples/python/src/booktest/models.py index 7367c14720..4ab5c6a28b 100644 --- a/examples/python/src/booktest/models.py +++ b/examples/python/src/booktest/models.py @@ -1,10 +1,8 @@ # Code generated by sqlc. DO NOT EDIT. -from typing import List +import dataclasses import datetime import enum - -import dataclasses - +from typing import List class BookType(str, enum.Enum): @@ -18,7 +16,6 @@ class Author: name: str - @dataclasses.dataclass() class Book: book_id: int @@ -29,5 +26,3 @@ class Book: year: int available: datetime.datetime tags: List[str] - - diff --git a/examples/python/src/booktest/query.py b/examples/python/src/booktest/query.py index ea8255237f..24fc9ded4f 100644 --- a/examples/python/src/booktest/query.py +++ b/examples/python/src/booktest/query.py @@ -1,9 +1,9 @@ # Code generated by sqlc. DO NOT EDIT. from typing import AsyncIterator, List, Optional +import dataclasses import datetime -import dataclasses import sqlalchemy import sqlalchemy.ext.asyncio diff --git a/examples/python/src/jets/models.py b/examples/python/src/jets/models.py index 13ff1a122c..67e2d4bffb 100644 --- a/examples/python/src/jets/models.py +++ b/examples/python/src/jets/models.py @@ -1,11 +1,7 @@ # Code generated by sqlc. DO NOT EDIT. - - import dataclasses - - @dataclasses.dataclass() class Jet: id: int @@ -15,24 +11,19 @@ class Jet: color: str - @dataclasses.dataclass() class Language: id: int language: str - @dataclasses.dataclass() class Pilot: id: int name: str - @dataclasses.dataclass() class PilotLanguage: pilot_id: int language_id: int - - diff --git a/examples/python/src/ondeck/models.py b/examples/python/src/ondeck/models.py index 6e2de33b5e..8ea4e6835a 100644 --- a/examples/python/src/ondeck/models.py +++ b/examples/python/src/ondeck/models.py @@ -1,13 +1,12 @@ # Code generated by sqlc. DO NOT EDIT. -from typing import List, Optional +import dataclasses import datetime import enum - -import dataclasses +from typing import List, Optional -# Venues can be either open or closed class Status(str, enum.Enum): + """Venues can be either open or closed""" OPEN = "op!en" CLOSED = "clo@sed" @@ -18,9 +17,9 @@ class City: name: str -# Venues are places where muisc happens @dataclasses.dataclass() class Venue: + """Venues are places where muisc happens""" id: int status: Status statuses: Optional[List[Status]] @@ -32,5 +31,3 @@ class Venue: songkick_id: Optional[str] tags: Optional[List[str]] created_at: datetime.datetime - - diff --git a/examples/python/src/ondeck/venue.py b/examples/python/src/ondeck/venue.py index c0e31be474..2d7273da5e 100644 --- a/examples/python/src/ondeck/venue.py +++ b/examples/python/src/ondeck/venue.py @@ -1,8 +1,8 @@ # Code generated by sqlc. DO NOT EDIT. from typing import AsyncIterator, List, Optional - import dataclasses + import sqlalchemy import sqlalchemy.ext.asyncio diff --git a/internal/codegen/python/gen.go b/internal/codegen/python/gen.go index 3173bc6d8f..97633c8e98 100644 --- a/internal/codegen/python/gen.go +++ b/internal/codegen/python/gen.go @@ -4,18 +4,21 @@ import ( "bufio" "bytes" "fmt" + "log" + "regexp" + "sort" + "strings" + "text/template" + "github.com/kyleconroy/sqlc/internal/codegen" "github.com/kyleconroy/sqlc/internal/compiler" "github.com/kyleconroy/sqlc/internal/config" "github.com/kyleconroy/sqlc/internal/core" "github.com/kyleconroy/sqlc/internal/inflection" + pyast "github.com/kyleconroy/sqlc/internal/python/ast" + pyprint "github.com/kyleconroy/sqlc/internal/python/printer" "github.com/kyleconroy/sqlc/internal/sql/ast" "github.com/kyleconroy/sqlc/internal/sql/catalog" - "log" - "regexp" - "sort" - "strings" - "text/template" ) type Constant struct { @@ -480,33 +483,216 @@ func buildQueries(r *compiler.Result, settings config.CombinedSettings, structs sort.Slice(qs, func(i, j int) bool { return qs[i].MethodName < qs[j].MethodName }) return qs } +func aliasNode(name string) *pyast.Node { + return &pyast.Node{ + Node: &pyast.Node_Alias{ + Alias: &pyast.Alias{ + Name: name, + }, + }, + } +} + +func importNode(name string) *pyast.Node { + return &pyast.Node{ + Node: &pyast.Node_Import{ + Import: &pyast.Import{ + Names: []*pyast.Node{ + { + Node: &pyast.Node_Alias{ + Alias: &pyast.Alias{ + Name: name, + }, + }, + }, + }, + }, + }, + } +} + +func classDefNode(name string, bases ...*pyast.Node) *pyast.Node { + return &pyast.Node{ + Node: &pyast.Node_ClassDef{ + ClassDef: &pyast.ClassDef{ + Name: name, + Bases: bases, + }, + }, + } +} + +func nameNode(id string) *pyast.Node { + return &pyast.Node{ + Node: &pyast.Node_Name{ + Name: &pyast.Name{Id: id}, + }, + } +} + +func attributeNode(value, attr string) *pyast.Node { + return &pyast.Node{ + Node: &pyast.Node_Attribute{ + Attribute: &pyast.Attribute{ + Value: &pyast.Name{Id: value}, + Attr: attr, + }, + }, + } +} + +func assignNode(target, value string) *pyast.Node { + return &pyast.Node{ + Node: &pyast.Node_Assign{ + Assign: &pyast.Assign{ + Targets: []*pyast.Name{ + {Id: target}, + }, + Value: &pyast.Node{ + Node: &pyast.Node_Constant{ + Constant: &pyast.Constant{ + Value: value, + }, + }, + }, + }, + }, + } +} + +func subscriptNode(value string, slice *pyast.Node) *pyast.Node { + return &pyast.Node{ + Node: &pyast.Node_Subscript{ + Subscript: &pyast.Subscript{ + Value: &pyast.Name{Id: value}, + Slice: slice, + }, + }, + } +} + +func buildModelsTree(ctx *pyTmplCtx, i *importer) *pyast.Node { + mod := &pyast.Module{ + Body: []*pyast.Node{ + { + Node: &pyast.Node_Comment{ + Comment: &pyast.Comment{ + Text: "Code generated by sqlc. DO NOT EDIT.", + }, + }, + }, + }, + } + std, pkg := i.modelImportSpecs() + + for _, specs := range []map[string]importSpec{std, pkg} { + for _, spec := range buildImportBlock2(specs) { + if len(spec.Names) > 0 && spec.Names[0] != "" { + imp := &pyast.ImportFrom{ + Module: spec.Module, + } + for _, name := range spec.Names { + imp.Names = append(imp.Names, aliasNode(name)) + } + mod.Body = append(mod.Body, &pyast.Node{ + Node: &pyast.Node_ImportFrom{ + ImportFrom: imp, + }, + }) + } else { + mod.Body = append(mod.Body, importNode(spec.Module)) + } + } + } -var modelsTmpl = `# Code generated by sqlc. DO NOT EDIT. -{{- range imports .SourceName}} -{{.}} -{{- end}} - - -{{range .Enums}} -{{- if .Comment}}{{comment .Comment}}{{- end}} -class {{.Name}}(str, enum.Enum): - {{- range .Constants}} - {{.Name}} = "{{.Value}}" - {{- end}} -{{end}} + for _, e := range ctx.Enums { + def := &pyast.ClassDef{ + Name: e.Name, + Bases: []*pyast.Node{ + nameNode("str"), + attributeNode("enum", "Enum"), + }, + } + if e.Comment != "" { + def.Body = append(def.Body, &pyast.Node{ + Node: &pyast.Node_Expr{ + Expr: &pyast.Expr{ + Value: &pyast.Node{ + Node: &pyast.Node_Constant{ + Constant: &pyast.Constant{ + Value: e.Comment, + }, + }, + }, + }, + }, + }) + } + for _, c := range e.Constants { + def.Body = append(def.Body, assignNode(c.Name, c.Value)) + } + mod.Body = append(mod.Body, &pyast.Node{ + Node: &pyast.Node_ClassDef{ + ClassDef: def, + }, + }) + } -{{- range .Models}} -{{if .Comment}}{{comment .Comment}}{{- end}} -@dataclasses.dataclass() -class {{.Name}}: {{- range .Fields}} - {{- if .Comment}} - {{comment .Comment}}{{else}} - {{- end}} - {{.Name}}: {{.Type}} - {{- end}} + for _, m := range ctx.Models { + def := &pyast.ClassDef{ + Name: m.Name, + DecoratorList: []*pyast.Node{ + { + Node: &pyast.Node_Call{ + Call: &pyast.Call{ + Func: attributeNode("dataclasses", "dataclass"), + }, + }, + }, + }, + } + if m.Comment != "" { + def.Body = append(def.Body, &pyast.Node{ + Node: &pyast.Node_Expr{ + Expr: &pyast.Expr{ + Value: &pyast.Node{ + Node: &pyast.Node_Constant{ + Constant: &pyast.Constant{ + Value: m.Comment, + }, + }, + }, + }, + }, + }) + } + for _, f := range m.Fields { + ann := nameNode(f.Type.InnerType) + if f.Type.IsArray { + ann = subscriptNode("List", ann) + } + if f.Type.IsNull { + ann = subscriptNode("Optional", ann) + } + def.Body = append(def.Body, &pyast.Node{ + Node: &pyast.Node_AnnAssign{ + AnnAssign: &pyast.AnnAssign{ + Target: &pyast.Name{Id: f.Name}, + Annotation: ann, + Comment: f.Comment, + }, + }, + }) + } + mod.Body = append(mod.Body, &pyast.Node{ + Node: &pyast.Node_ClassDef{ + ClassDef: def, + }, + }) + } -{{end}} -` + return &pyast.Node{Node: &pyast.Node_Module{Module: mod}} +} var queriesTmpl = ` {{- define "dataclassParse"}} @@ -673,7 +859,6 @@ func Generate(r *compiler.Result, settings config.CombinedSettings) (map[string] "imports": i.Imports, } - modelsFile := template.Must(template.New("table").Funcs(funcMap).Parse(modelsTmpl)) queriesFile := template.Must(template.New("table").Funcs(funcMap).Parse(queriesTmpl)) tctx := pyTmplCtx{ @@ -703,9 +888,8 @@ func Generate(r *compiler.Result, settings config.CombinedSettings) (map[string] return nil } - if err := execute("models.py", modelsFile); err != nil { - return nil, err - } + result := pyprint.Print(buildModelsTree(&tctx, i), pyprint.Options{}) + output["models.py"] = string(result.Python) files := map[string]struct{}{} for _, q := range queries { diff --git a/internal/codegen/python/imports.go b/internal/codegen/python/imports.go index dfce83a085..4947e52840 100644 --- a/internal/codegen/python/imports.go +++ b/internal/codegen/python/imports.go @@ -2,9 +2,10 @@ package python import ( "fmt" - "github.com/kyleconroy/sqlc/internal/config" "sort" "strings" + + "github.com/kyleconroy/sqlc/internal/config" ) type importSpec struct { @@ -76,7 +77,7 @@ func (i *importer) Imports(fileName string) []string { return i.queryImports(fileName) } -func (i *importer) modelImports() []string { +func (i *importer) modelImportSpecs() (map[string]importSpec, map[string]importSpec) { modelUses := func(name string) bool { for _, model := range i.Models { if structUses(name, model) { @@ -87,12 +88,12 @@ func (i *importer) modelImports() []string { } std := stdImports(modelUses) + std["dataclasses"] = importSpec{Module: "dataclasses"} if len(i.Enums) > 0 { std["enum"] = importSpec{Module: "enum"} } pkg := make(map[string]importSpec) - pkg["dataclasses"] = importSpec{Module: "dataclasses"} for _, o := range i.Settings.Overrides { if o.PythonType.IsSet() && o.PythonType.Module != "" { @@ -101,7 +102,11 @@ func (i *importer) modelImports() []string { } } } + return std, pkg +} +func (i *importer) modelImports() []string { + std, pkg := i.modelImportSpecs() importLines := []string{ buildImportBlock(std), "", @@ -146,7 +151,7 @@ func (i *importer) queryImports(fileName string) []string { queryValueModelImports := func(qv QueryValue) { if qv.IsStruct() && qv.EmitStruct() { - pkg["dataclasses"] = importSpec{Module: "dataclasses"} + std["dataclasses"] = importSpec{Module: "dataclasses"} } } @@ -183,6 +188,44 @@ func (i *importer) queryImports(fileName string) []string { return importLines } +type importFromSpec struct { + Module string + Names []string + Alias string +} + +func buildImportBlock2(pkgs map[string]importSpec) []importFromSpec { + pkgImports := make([]importFromSpec, 0) + fromImports := make(map[string][]string) + for _, is := range pkgs { + if is.Name == "" || is.Alias != "" { + pkgImports = append(pkgImports, importFromSpec{ + Module: is.Module, + Names: []string{is.Name}, + Alias: is.Alias, + }) + } else { + names, ok := fromImports[is.Module] + if !ok { + names = make([]string, 0, 1) + } + names = append(names, is.Name) + fromImports[is.Module] = names + } + } + for modName, names := range fromImports { + sort.Strings(names) + pkgImports = append(pkgImports, importFromSpec{ + Module: modName, + Names: names, + }) + } + sort.Slice(pkgImports, func(i, j int) bool { + return pkgImports[i].Module < pkgImports[j].Module || pkgImports[i].Names[0] < pkgImports[j].Names[0] + }) + return pkgImports +} + func buildImportBlock(pkgs map[string]importSpec) string { pkgImports := make([]importSpec, 0) fromImports := make(map[string][]string) diff --git a/internal/python/ast/ast.pb.go b/internal/python/ast/ast.pb.go new file mode 100644 index 0000000000..f32295bb59 --- /dev/null +++ b/internal/python/ast/ast.pb.go @@ -0,0 +1,1432 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.27.1 +// protoc v3.17.3 +// source: python/ast.proto + +package ast + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type Node struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to Node: + // *Node_ClassDef + // *Node_Import + // *Node_ImportFrom + // *Node_Module + // *Node_Alias + // *Node_AnnAssign + // *Node_Name + // *Node_Subscript + // *Node_Attribute + // *Node_Constant + // *Node_Assign + // *Node_Comment + // *Node_Expr + // *Node_Call + Node isNode_Node `protobuf_oneof:"node"` +} + +func (x *Node) Reset() { + *x = Node{} + if protoimpl.UnsafeEnabled { + mi := &file_python_ast_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Node) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Node) ProtoMessage() {} + +func (x *Node) ProtoReflect() protoreflect.Message { + mi := &file_python_ast_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Node.ProtoReflect.Descriptor instead. +func (*Node) Descriptor() ([]byte, []int) { + return file_python_ast_proto_rawDescGZIP(), []int{0} +} + +func (m *Node) GetNode() isNode_Node { + if m != nil { + return m.Node + } + return nil +} + +func (x *Node) GetClassDef() *ClassDef { + if x, ok := x.GetNode().(*Node_ClassDef); ok { + return x.ClassDef + } + return nil +} + +func (x *Node) GetImport() *Import { + if x, ok := x.GetNode().(*Node_Import); ok { + return x.Import + } + return nil +} + +func (x *Node) GetImportFrom() *ImportFrom { + if x, ok := x.GetNode().(*Node_ImportFrom); ok { + return x.ImportFrom + } + return nil +} + +func (x *Node) GetModule() *Module { + if x, ok := x.GetNode().(*Node_Module); ok { + return x.Module + } + return nil +} + +func (x *Node) GetAlias() *Alias { + if x, ok := x.GetNode().(*Node_Alias); ok { + return x.Alias + } + return nil +} + +func (x *Node) GetAnnAssign() *AnnAssign { + if x, ok := x.GetNode().(*Node_AnnAssign); ok { + return x.AnnAssign + } + return nil +} + +func (x *Node) GetName() *Name { + if x, ok := x.GetNode().(*Node_Name); ok { + return x.Name + } + return nil +} + +func (x *Node) GetSubscript() *Subscript { + if x, ok := x.GetNode().(*Node_Subscript); ok { + return x.Subscript + } + return nil +} + +func (x *Node) GetAttribute() *Attribute { + if x, ok := x.GetNode().(*Node_Attribute); ok { + return x.Attribute + } + return nil +} + +func (x *Node) GetConstant() *Constant { + if x, ok := x.GetNode().(*Node_Constant); ok { + return x.Constant + } + return nil +} + +func (x *Node) GetAssign() *Assign { + if x, ok := x.GetNode().(*Node_Assign); ok { + return x.Assign + } + return nil +} + +func (x *Node) GetComment() *Comment { + if x, ok := x.GetNode().(*Node_Comment); ok { + return x.Comment + } + return nil +} + +func (x *Node) GetExpr() *Expr { + if x, ok := x.GetNode().(*Node_Expr); ok { + return x.Expr + } + return nil +} + +func (x *Node) GetCall() *Call { + if x, ok := x.GetNode().(*Node_Call); ok { + return x.Call + } + return nil +} + +type isNode_Node interface { + isNode_Node() +} + +type Node_ClassDef struct { + ClassDef *ClassDef `protobuf:"bytes,1,opt,name=class_def,json=ClassDef,proto3,oneof"` +} + +type Node_Import struct { + Import *Import `protobuf:"bytes,2,opt,name=import,json=Import,proto3,oneof"` +} + +type Node_ImportFrom struct { + ImportFrom *ImportFrom `protobuf:"bytes,3,opt,name=import_from,json=ImportFrom,proto3,oneof"` +} + +type Node_Module struct { + Module *Module `protobuf:"bytes,4,opt,name=module,json=Module,proto3,oneof"` +} + +type Node_Alias struct { + Alias *Alias `protobuf:"bytes,5,opt,name=alias,json=Alias,proto3,oneof"` +} + +type Node_AnnAssign struct { + AnnAssign *AnnAssign `protobuf:"bytes,6,opt,name=ann_assign,json=AnnAssign,proto3,oneof"` +} + +type Node_Name struct { + Name *Name `protobuf:"bytes,7,opt,name=name,json=Name,proto3,oneof"` +} + +type Node_Subscript struct { + Subscript *Subscript `protobuf:"bytes,8,opt,name=subscript,json=Subscript,proto3,oneof"` +} + +type Node_Attribute struct { + Attribute *Attribute `protobuf:"bytes,9,opt,name=attribute,json=Attribute,proto3,oneof"` +} + +type Node_Constant struct { + Constant *Constant `protobuf:"bytes,10,opt,name=constant,json=Constant,proto3,oneof"` +} + +type Node_Assign struct { + Assign *Assign `protobuf:"bytes,11,opt,name=assign,json=Assign,proto3,oneof"` +} + +type Node_Comment struct { + Comment *Comment `protobuf:"bytes,12,opt,name=comment,json=Comment,proto3,oneof"` +} + +type Node_Expr struct { + Expr *Expr `protobuf:"bytes,13,opt,name=expr,json=Expr,proto3,oneof"` +} + +type Node_Call struct { + Call *Call `protobuf:"bytes,14,opt,name=call,json=Call,proto3,oneof"` +} + +func (*Node_ClassDef) isNode_Node() {} + +func (*Node_Import) isNode_Node() {} + +func (*Node_ImportFrom) isNode_Node() {} + +func (*Node_Module) isNode_Node() {} + +func (*Node_Alias) isNode_Node() {} + +func (*Node_AnnAssign) isNode_Node() {} + +func (*Node_Name) isNode_Node() {} + +func (*Node_Subscript) isNode_Node() {} + +func (*Node_Attribute) isNode_Node() {} + +func (*Node_Constant) isNode_Node() {} + +func (*Node_Assign) isNode_Node() {} + +func (*Node_Comment) isNode_Node() {} + +func (*Node_Expr) isNode_Node() {} + +func (*Node_Call) isNode_Node() {} + +type Alias struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` +} + +func (x *Alias) Reset() { + *x = Alias{} + if protoimpl.UnsafeEnabled { + mi := &file_python_ast_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Alias) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Alias) ProtoMessage() {} + +func (x *Alias) ProtoReflect() protoreflect.Message { + mi := &file_python_ast_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Alias.ProtoReflect.Descriptor instead. +func (*Alias) Descriptor() ([]byte, []int) { + return file_python_ast_proto_rawDescGZIP(), []int{1} +} + +func (x *Alias) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +type Attribute struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Value *Name `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"` + Attr string `protobuf:"bytes,2,opt,name=attr,proto3" json:"attr,omitempty"` +} + +func (x *Attribute) Reset() { + *x = Attribute{} + if protoimpl.UnsafeEnabled { + mi := &file_python_ast_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Attribute) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Attribute) ProtoMessage() {} + +func (x *Attribute) ProtoReflect() protoreflect.Message { + mi := &file_python_ast_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Attribute.ProtoReflect.Descriptor instead. +func (*Attribute) Descriptor() ([]byte, []int) { + return file_python_ast_proto_rawDescGZIP(), []int{2} +} + +func (x *Attribute) GetValue() *Name { + if x != nil { + return x.Value + } + return nil +} + +func (x *Attribute) GetAttr() string { + if x != nil { + return x.Attr + } + return "" +} + +type AnnAssign struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Target *Name `protobuf:"bytes,1,opt,name=target,proto3" json:"target,omitempty"` + Annotation *Node `protobuf:"bytes,2,opt,name=annotation,proto3" json:"annotation,omitempty"` + Simple int32 `protobuf:"varint,3,opt,name=simple,proto3" json:"simple,omitempty"` + Comment string `protobuf:"bytes,4,opt,name=Comment,json=comment,proto3" json:"Comment,omitempty"` +} + +func (x *AnnAssign) Reset() { + *x = AnnAssign{} + if protoimpl.UnsafeEnabled { + mi := &file_python_ast_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AnnAssign) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AnnAssign) ProtoMessage() {} + +func (x *AnnAssign) ProtoReflect() protoreflect.Message { + mi := &file_python_ast_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AnnAssign.ProtoReflect.Descriptor instead. +func (*AnnAssign) Descriptor() ([]byte, []int) { + return file_python_ast_proto_rawDescGZIP(), []int{3} +} + +func (x *AnnAssign) GetTarget() *Name { + if x != nil { + return x.Target + } + return nil +} + +func (x *AnnAssign) GetAnnotation() *Node { + if x != nil { + return x.Annotation + } + return nil +} + +func (x *AnnAssign) GetSimple() int32 { + if x != nil { + return x.Simple + } + return 0 +} + +func (x *AnnAssign) GetComment() string { + if x != nil { + return x.Comment + } + return "" +} + +type Assign struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Targets []*Name `protobuf:"bytes,1,rep,name=targets,proto3" json:"targets,omitempty"` + Value *Node `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` + Comment string `protobuf:"bytes,3,opt,name=Comment,json=comment,proto3" json:"Comment,omitempty"` +} + +func (x *Assign) Reset() { + *x = Assign{} + if protoimpl.UnsafeEnabled { + mi := &file_python_ast_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Assign) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Assign) ProtoMessage() {} + +func (x *Assign) ProtoReflect() protoreflect.Message { + mi := &file_python_ast_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Assign.ProtoReflect.Descriptor instead. +func (*Assign) Descriptor() ([]byte, []int) { + return file_python_ast_proto_rawDescGZIP(), []int{4} +} + +func (x *Assign) GetTargets() []*Name { + if x != nil { + return x.Targets + } + return nil +} + +func (x *Assign) GetValue() *Node { + if x != nil { + return x.Value + } + return nil +} + +func (x *Assign) GetComment() string { + if x != nil { + return x.Comment + } + return "" +} + +type Call struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Func *Node `protobuf:"bytes,1,opt,name=func,proto3" json:"func,omitempty"` +} + +func (x *Call) Reset() { + *x = Call{} + if protoimpl.UnsafeEnabled { + mi := &file_python_ast_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Call) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Call) ProtoMessage() {} + +func (x *Call) ProtoReflect() protoreflect.Message { + mi := &file_python_ast_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Call.ProtoReflect.Descriptor instead. +func (*Call) Descriptor() ([]byte, []int) { + return file_python_ast_proto_rawDescGZIP(), []int{5} +} + +func (x *Call) GetFunc() *Node { + if x != nil { + return x.Func + } + return nil +} + +type ClassDef struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Bases []*Node `protobuf:"bytes,2,rep,name=bases,proto3" json:"bases,omitempty"` + Keywords []*Node `protobuf:"bytes,3,rep,name=keywords,proto3" json:"keywords,omitempty"` + Body []*Node `protobuf:"bytes,4,rep,name=body,proto3" json:"body,omitempty"` + DecoratorList []*Node `protobuf:"bytes,5,rep,name=decorator_list,proto3" json:"decorator_list,omitempty"` +} + +func (x *ClassDef) Reset() { + *x = ClassDef{} + if protoimpl.UnsafeEnabled { + mi := &file_python_ast_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ClassDef) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ClassDef) ProtoMessage() {} + +func (x *ClassDef) ProtoReflect() protoreflect.Message { + mi := &file_python_ast_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ClassDef.ProtoReflect.Descriptor instead. +func (*ClassDef) Descriptor() ([]byte, []int) { + return file_python_ast_proto_rawDescGZIP(), []int{6} +} + +func (x *ClassDef) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *ClassDef) GetBases() []*Node { + if x != nil { + return x.Bases + } + return nil +} + +func (x *ClassDef) GetKeywords() []*Node { + if x != nil { + return x.Keywords + } + return nil +} + +func (x *ClassDef) GetBody() []*Node { + if x != nil { + return x.Body + } + return nil +} + +func (x *ClassDef) GetDecoratorList() []*Node { + if x != nil { + return x.DecoratorList + } + return nil +} + +// The Python ast module does not parse comments. It's not clear if this is the +// best way to support them in the AST +type Comment struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Text string `protobuf:"bytes,1,opt,name=text,proto3" json:"text,omitempty"` +} + +func (x *Comment) Reset() { + *x = Comment{} + if protoimpl.UnsafeEnabled { + mi := &file_python_ast_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Comment) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Comment) ProtoMessage() {} + +func (x *Comment) ProtoReflect() protoreflect.Message { + mi := &file_python_ast_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Comment.ProtoReflect.Descriptor instead. +func (*Comment) Descriptor() ([]byte, []int) { + return file_python_ast_proto_rawDescGZIP(), []int{7} +} + +func (x *Comment) GetText() string { + if x != nil { + return x.Text + } + return "" +} + +type Constant struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Value string `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"` +} + +func (x *Constant) Reset() { + *x = Constant{} + if protoimpl.UnsafeEnabled { + mi := &file_python_ast_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Constant) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Constant) ProtoMessage() {} + +func (x *Constant) ProtoReflect() protoreflect.Message { + mi := &file_python_ast_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Constant.ProtoReflect.Descriptor instead. +func (*Constant) Descriptor() ([]byte, []int) { + return file_python_ast_proto_rawDescGZIP(), []int{8} +} + +func (x *Constant) GetValue() string { + if x != nil { + return x.Value + } + return "" +} + +type Expr struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Value *Node `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"` +} + +func (x *Expr) Reset() { + *x = Expr{} + if protoimpl.UnsafeEnabled { + mi := &file_python_ast_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Expr) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Expr) ProtoMessage() {} + +func (x *Expr) ProtoReflect() protoreflect.Message { + mi := &file_python_ast_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Expr.ProtoReflect.Descriptor instead. +func (*Expr) Descriptor() ([]byte, []int) { + return file_python_ast_proto_rawDescGZIP(), []int{9} +} + +func (x *Expr) GetValue() *Node { + if x != nil { + return x.Value + } + return nil +} + +type Import struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Names []*Node `protobuf:"bytes,1,rep,name=names,proto3" json:"names,omitempty"` +} + +func (x *Import) Reset() { + *x = Import{} + if protoimpl.UnsafeEnabled { + mi := &file_python_ast_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Import) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Import) ProtoMessage() {} + +func (x *Import) ProtoReflect() protoreflect.Message { + mi := &file_python_ast_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Import.ProtoReflect.Descriptor instead. +func (*Import) Descriptor() ([]byte, []int) { + return file_python_ast_proto_rawDescGZIP(), []int{10} +} + +func (x *Import) GetNames() []*Node { + if x != nil { + return x.Names + } + return nil +} + +type ImportFrom struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Module string `protobuf:"bytes,1,opt,name=module,proto3" json:"module,omitempty"` + Names []*Node `protobuf:"bytes,2,rep,name=names,proto3" json:"names,omitempty"` + Level int32 `protobuf:"varint,3,opt,name=level,proto3" json:"level,omitempty"` +} + +func (x *ImportFrom) Reset() { + *x = ImportFrom{} + if protoimpl.UnsafeEnabled { + mi := &file_python_ast_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ImportFrom) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ImportFrom) ProtoMessage() {} + +func (x *ImportFrom) ProtoReflect() protoreflect.Message { + mi := &file_python_ast_proto_msgTypes[11] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ImportFrom.ProtoReflect.Descriptor instead. +func (*ImportFrom) Descriptor() ([]byte, []int) { + return file_python_ast_proto_rawDescGZIP(), []int{11} +} + +func (x *ImportFrom) GetModule() string { + if x != nil { + return x.Module + } + return "" +} + +func (x *ImportFrom) GetNames() []*Node { + if x != nil { + return x.Names + } + return nil +} + +func (x *ImportFrom) GetLevel() int32 { + if x != nil { + return x.Level + } + return 0 +} + +type Module struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Body []*Node `protobuf:"bytes,1,rep,name=body,proto3" json:"body,omitempty"` +} + +func (x *Module) Reset() { + *x = Module{} + if protoimpl.UnsafeEnabled { + mi := &file_python_ast_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Module) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Module) ProtoMessage() {} + +func (x *Module) ProtoReflect() protoreflect.Message { + mi := &file_python_ast_proto_msgTypes[12] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Module.ProtoReflect.Descriptor instead. +func (*Module) Descriptor() ([]byte, []int) { + return file_python_ast_proto_rawDescGZIP(), []int{12} +} + +func (x *Module) GetBody() []*Node { + if x != nil { + return x.Body + } + return nil +} + +type Name struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` +} + +func (x *Name) Reset() { + *x = Name{} + if protoimpl.UnsafeEnabled { + mi := &file_python_ast_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Name) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Name) ProtoMessage() {} + +func (x *Name) ProtoReflect() protoreflect.Message { + mi := &file_python_ast_proto_msgTypes[13] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Name.ProtoReflect.Descriptor instead. +func (*Name) Descriptor() ([]byte, []int) { + return file_python_ast_proto_rawDescGZIP(), []int{13} +} + +func (x *Name) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +type Subscript struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Value *Name `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"` + Slice *Node `protobuf:"bytes,2,opt,name=slice,proto3" json:"slice,omitempty"` +} + +func (x *Subscript) Reset() { + *x = Subscript{} + if protoimpl.UnsafeEnabled { + mi := &file_python_ast_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Subscript) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Subscript) ProtoMessage() {} + +func (x *Subscript) ProtoReflect() protoreflect.Message { + mi := &file_python_ast_proto_msgTypes[14] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Subscript.ProtoReflect.Descriptor instead. +func (*Subscript) Descriptor() ([]byte, []int) { + return file_python_ast_proto_rawDescGZIP(), []int{14} +} + +func (x *Subscript) GetValue() *Name { + if x != nil { + return x.Value + } + return nil +} + +func (x *Subscript) GetSlice() *Node { + if x != nil { + return x.Slice + } + return nil +} + +var File_python_ast_proto protoreflect.FileDescriptor + +var file_python_ast_proto_rawDesc = []byte{ + 0x0a, 0x10, 0x70, 0x79, 0x74, 0x68, 0x6f, 0x6e, 0x2f, 0x61, 0x73, 0x74, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x12, 0x03, 0x61, 0x73, 0x74, 0x22, 0xd4, 0x04, 0x0a, 0x04, 0x4e, 0x6f, 0x64, 0x65, + 0x12, 0x2c, 0x0a, 0x09, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x5f, 0x64, 0x65, 0x66, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x61, 0x73, 0x74, 0x2e, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x44, + 0x65, 0x66, 0x48, 0x00, 0x52, 0x08, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x44, 0x65, 0x66, 0x12, 0x25, + 0x0a, 0x06, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, + 0x2e, 0x61, 0x73, 0x74, 0x2e, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x48, 0x00, 0x52, 0x06, 0x49, + 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x32, 0x0a, 0x0b, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x5f, + 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x61, 0x73, 0x74, + 0x2e, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x46, 0x72, 0x6f, 0x6d, 0x48, 0x00, 0x52, 0x0a, 0x49, + 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x46, 0x72, 0x6f, 0x6d, 0x12, 0x25, 0x0a, 0x06, 0x6d, 0x6f, 0x64, + 0x75, 0x6c, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x61, 0x73, 0x74, 0x2e, + 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x48, 0x00, 0x52, 0x06, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, + 0x12, 0x22, 0x0a, 0x05, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x0a, 0x2e, 0x61, 0x73, 0x74, 0x2e, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x48, 0x00, 0x52, 0x05, 0x41, + 0x6c, 0x69, 0x61, 0x73, 0x12, 0x2f, 0x0a, 0x0a, 0x61, 0x6e, 0x6e, 0x5f, 0x61, 0x73, 0x73, 0x69, + 0x67, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x61, 0x73, 0x74, 0x2e, 0x41, + 0x6e, 0x6e, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x48, 0x00, 0x52, 0x09, 0x41, 0x6e, 0x6e, 0x41, + 0x73, 0x73, 0x69, 0x67, 0x6e, 0x12, 0x1f, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x07, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x61, 0x73, 0x74, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x48, 0x00, + 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2e, 0x0a, 0x09, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, + 0x69, 0x70, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x61, 0x73, 0x74, 0x2e, + 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x48, 0x00, 0x52, 0x09, 0x53, 0x75, 0x62, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x12, 0x2e, 0x0a, 0x09, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, + 0x75, 0x74, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x61, 0x73, 0x74, 0x2e, + 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x48, 0x00, 0x52, 0x09, 0x41, 0x74, 0x74, + 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x12, 0x2b, 0x0a, 0x08, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x61, 0x73, 0x74, 0x2e, 0x43, + 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x08, 0x43, 0x6f, 0x6e, 0x73, 0x74, + 0x61, 0x6e, 0x74, 0x12, 0x25, 0x0a, 0x06, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x18, 0x0b, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, 0x61, 0x73, 0x74, 0x2e, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, + 0x48, 0x00, 0x52, 0x06, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x12, 0x28, 0x0a, 0x07, 0x63, 0x6f, + 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x61, 0x73, + 0x74, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x07, 0x43, 0x6f, 0x6d, + 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x1f, 0x0a, 0x04, 0x65, 0x78, 0x70, 0x72, 0x18, 0x0d, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x61, 0x73, 0x74, 0x2e, 0x45, 0x78, 0x70, 0x72, 0x48, 0x00, 0x52, + 0x04, 0x45, 0x78, 0x70, 0x72, 0x12, 0x1f, 0x0a, 0x04, 0x63, 0x61, 0x6c, 0x6c, 0x18, 0x0e, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x61, 0x73, 0x74, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x48, 0x00, + 0x52, 0x04, 0x43, 0x61, 0x6c, 0x6c, 0x42, 0x06, 0x0a, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x22, 0x1b, + 0x0a, 0x05, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x40, 0x0a, 0x09, 0x41, + 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x12, 0x1f, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x61, 0x73, 0x74, 0x2e, 0x4e, 0x61, + 0x6d, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x74, 0x74, + 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x61, 0x74, 0x74, 0x72, 0x22, 0x8b, 0x01, + 0x0a, 0x09, 0x41, 0x6e, 0x6e, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x12, 0x21, 0x0a, 0x06, 0x74, + 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x61, 0x73, + 0x74, 0x2e, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x29, + 0x0a, 0x0a, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x61, 0x73, 0x74, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x0a, 0x61, + 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x69, 0x6d, + 0x70, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x73, 0x69, 0x6d, 0x70, 0x6c, + 0x65, 0x12, 0x18, 0x0a, 0x07, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x68, 0x0a, 0x06, 0x41, + 0x73, 0x73, 0x69, 0x67, 0x6e, 0x12, 0x23, 0x0a, 0x07, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x61, 0x73, 0x74, 0x2e, 0x4e, 0x61, 0x6d, + 0x65, 0x52, 0x07, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, 0x12, 0x1f, 0x0a, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x61, 0x73, 0x74, 0x2e, + 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x43, + 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, + 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x25, 0x0a, 0x04, 0x43, 0x61, 0x6c, 0x6c, 0x12, 0x1d, 0x0a, + 0x04, 0x66, 0x75, 0x6e, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x61, 0x73, + 0x74, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x66, 0x75, 0x6e, 0x63, 0x22, 0xb8, 0x01, 0x0a, + 0x08, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x44, 0x65, 0x66, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, + 0x05, 0x62, 0x61, 0x73, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x61, + 0x73, 0x74, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x05, 0x62, 0x61, 0x73, 0x65, 0x73, 0x12, 0x25, + 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x09, 0x2e, 0x61, 0x73, 0x74, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x08, 0x6b, 0x65, 0x79, + 0x77, 0x6f, 0x72, 0x64, 0x73, 0x12, 0x1d, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x04, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x61, 0x73, 0x74, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x04, + 0x62, 0x6f, 0x64, 0x79, 0x12, 0x31, 0x0a, 0x0e, 0x64, 0x65, 0x63, 0x6f, 0x72, 0x61, 0x74, 0x6f, + 0x72, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x61, + 0x73, 0x74, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x0e, 0x64, 0x65, 0x63, 0x6f, 0x72, 0x61, 0x74, + 0x6f, 0x72, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x22, 0x1d, 0x0a, 0x07, 0x43, 0x6f, 0x6d, 0x6d, 0x65, + 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x65, 0x78, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x74, 0x65, 0x78, 0x74, 0x22, 0x20, 0x0a, 0x08, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x27, 0x0a, 0x04, 0x45, 0x78, 0x70, 0x72, + 0x12, 0x1f, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x09, 0x2e, 0x61, 0x73, 0x74, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x22, 0x29, 0x0a, 0x06, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x1f, 0x0a, 0x05, 0x6e, + 0x61, 0x6d, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x61, 0x73, 0x74, + 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x05, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x22, 0x5b, 0x0a, 0x0a, + 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x46, 0x72, 0x6f, 0x6d, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x6f, + 0x64, 0x75, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6d, 0x6f, 0x64, 0x75, + 0x6c, 0x65, 0x12, 0x1f, 0x0a, 0x05, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x09, 0x2e, 0x61, 0x73, 0x74, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x05, 0x6e, 0x61, + 0x6d, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x05, 0x52, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x22, 0x27, 0x0a, 0x06, 0x4d, 0x6f, 0x64, + 0x75, 0x6c, 0x65, 0x12, 0x1d, 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x09, 0x2e, 0x61, 0x73, 0x74, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x62, 0x6f, + 0x64, 0x79, 0x22, 0x16, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x4d, 0x0a, 0x09, 0x53, 0x75, + 0x62, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x12, 0x1f, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x61, 0x73, 0x74, 0x2e, 0x4e, 0x61, 0x6d, + 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1f, 0x0a, 0x05, 0x73, 0x6c, 0x69, 0x63, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x61, 0x73, 0x74, 0x2e, 0x4e, 0x6f, + 0x64, 0x65, 0x52, 0x05, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x42, 0x30, 0x5a, 0x2e, 0x67, 0x69, 0x74, + 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6b, 0x79, 0x6c, 0x65, 0x63, 0x6f, 0x6e, 0x72, + 0x6f, 0x79, 0x2f, 0x73, 0x71, 0x6c, 0x63, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, + 0x2f, 0x70, 0x79, 0x74, 0x68, 0x6f, 0x6e, 0x2f, 0x61, 0x73, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, +} + +var ( + file_python_ast_proto_rawDescOnce sync.Once + file_python_ast_proto_rawDescData = file_python_ast_proto_rawDesc +) + +func file_python_ast_proto_rawDescGZIP() []byte { + file_python_ast_proto_rawDescOnce.Do(func() { + file_python_ast_proto_rawDescData = protoimpl.X.CompressGZIP(file_python_ast_proto_rawDescData) + }) + return file_python_ast_proto_rawDescData +} + +var file_python_ast_proto_msgTypes = make([]protoimpl.MessageInfo, 15) +var file_python_ast_proto_goTypes = []interface{}{ + (*Node)(nil), // 0: ast.Node + (*Alias)(nil), // 1: ast.Alias + (*Attribute)(nil), // 2: ast.Attribute + (*AnnAssign)(nil), // 3: ast.AnnAssign + (*Assign)(nil), // 4: ast.Assign + (*Call)(nil), // 5: ast.Call + (*ClassDef)(nil), // 6: ast.ClassDef + (*Comment)(nil), // 7: ast.Comment + (*Constant)(nil), // 8: ast.Constant + (*Expr)(nil), // 9: ast.Expr + (*Import)(nil), // 10: ast.Import + (*ImportFrom)(nil), // 11: ast.ImportFrom + (*Module)(nil), // 12: ast.Module + (*Name)(nil), // 13: ast.Name + (*Subscript)(nil), // 14: ast.Subscript +} +var file_python_ast_proto_depIdxs = []int32{ + 6, // 0: ast.Node.class_def:type_name -> ast.ClassDef + 10, // 1: ast.Node.import:type_name -> ast.Import + 11, // 2: ast.Node.import_from:type_name -> ast.ImportFrom + 12, // 3: ast.Node.module:type_name -> ast.Module + 1, // 4: ast.Node.alias:type_name -> ast.Alias + 3, // 5: ast.Node.ann_assign:type_name -> ast.AnnAssign + 13, // 6: ast.Node.name:type_name -> ast.Name + 14, // 7: ast.Node.subscript:type_name -> ast.Subscript + 2, // 8: ast.Node.attribute:type_name -> ast.Attribute + 8, // 9: ast.Node.constant:type_name -> ast.Constant + 4, // 10: ast.Node.assign:type_name -> ast.Assign + 7, // 11: ast.Node.comment:type_name -> ast.Comment + 9, // 12: ast.Node.expr:type_name -> ast.Expr + 5, // 13: ast.Node.call:type_name -> ast.Call + 13, // 14: ast.Attribute.value:type_name -> ast.Name + 13, // 15: ast.AnnAssign.target:type_name -> ast.Name + 0, // 16: ast.AnnAssign.annotation:type_name -> ast.Node + 13, // 17: ast.Assign.targets:type_name -> ast.Name + 0, // 18: ast.Assign.value:type_name -> ast.Node + 0, // 19: ast.Call.func:type_name -> ast.Node + 0, // 20: ast.ClassDef.bases:type_name -> ast.Node + 0, // 21: ast.ClassDef.keywords:type_name -> ast.Node + 0, // 22: ast.ClassDef.body:type_name -> ast.Node + 0, // 23: ast.ClassDef.decorator_list:type_name -> ast.Node + 0, // 24: ast.Expr.value:type_name -> ast.Node + 0, // 25: ast.Import.names:type_name -> ast.Node + 0, // 26: ast.ImportFrom.names:type_name -> ast.Node + 0, // 27: ast.Module.body:type_name -> ast.Node + 13, // 28: ast.Subscript.value:type_name -> ast.Name + 0, // 29: ast.Subscript.slice:type_name -> ast.Node + 30, // [30:30] is the sub-list for method output_type + 30, // [30:30] is the sub-list for method input_type + 30, // [30:30] is the sub-list for extension type_name + 30, // [30:30] is the sub-list for extension extendee + 0, // [0:30] is the sub-list for field type_name +} + +func init() { file_python_ast_proto_init() } +func file_python_ast_proto_init() { + if File_python_ast_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_python_ast_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Node); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_python_ast_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Alias); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_python_ast_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Attribute); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_python_ast_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AnnAssign); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_python_ast_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Assign); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_python_ast_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Call); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_python_ast_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ClassDef); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_python_ast_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Comment); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_python_ast_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Constant); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_python_ast_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Expr); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_python_ast_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Import); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_python_ast_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ImportFrom); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_python_ast_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Module); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_python_ast_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Name); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_python_ast_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Subscript); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_python_ast_proto_msgTypes[0].OneofWrappers = []interface{}{ + (*Node_ClassDef)(nil), + (*Node_Import)(nil), + (*Node_ImportFrom)(nil), + (*Node_Module)(nil), + (*Node_Alias)(nil), + (*Node_AnnAssign)(nil), + (*Node_Name)(nil), + (*Node_Subscript)(nil), + (*Node_Attribute)(nil), + (*Node_Constant)(nil), + (*Node_Assign)(nil), + (*Node_Comment)(nil), + (*Node_Expr)(nil), + (*Node_Call)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_python_ast_proto_rawDesc, + NumEnums: 0, + NumMessages: 15, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_python_ast_proto_goTypes, + DependencyIndexes: file_python_ast_proto_depIdxs, + MessageInfos: file_python_ast_proto_msgTypes, + }.Build() + File_python_ast_proto = out.File + file_python_ast_proto_rawDesc = nil + file_python_ast_proto_goTypes = nil + file_python_ast_proto_depIdxs = nil +} diff --git a/internal/python/printer/printer.go b/internal/python/printer/printer.go new file mode 100644 index 0000000000..977dd86b05 --- /dev/null +++ b/internal/python/printer/printer.go @@ -0,0 +1,216 @@ +package printer + +import "github.com/kyleconroy/sqlc/internal/python/ast" + +type writer struct { + options Options + src []byte +} + +type Options struct { +} + +type PrintResult struct { + Python []byte +} + +func Print(node *ast.Node, options Options) PrintResult { + w := writer{options: options} + w.printNode(node, 0) + return PrintResult{ + Python: w.src, + } +} + +func (w *writer) print(text string) { + w.src = append(w.src, text...) +} + +func (w *writer) printIndent(indent int32) { + for i, n := 0, int(indent); i < n; i++ { + w.src = append(w.src, " "...) + } +} + +func (w *writer) printNode(node *ast.Node, indent int32) { + switch n := node.Node.(type) { + + case *ast.Node_Alias: + w.print(n.Alias.Name) + + case *ast.Node_AnnAssign: + w.printAnnAssign(n.AnnAssign, indent) + + case *ast.Node_Assign: + w.printAssign(n.Assign, indent) + + case *ast.Node_Attribute: + w.printAttribute(n.Attribute, indent) + + case *ast.Node_Call: + w.printCall(n.Call, indent) + + case *ast.Node_ClassDef: + w.printClassDef(n.ClassDef, indent) + + case *ast.Node_Comment: + w.printComment(n.Comment, indent) + + case *ast.Node_Constant: + w.printConstant(n.Constant, indent) + + case *ast.Node_Expr: + w.printNode(n.Expr.Value, indent) + + case *ast.Node_Import: + w.printImport(n.Import, indent) + + case *ast.Node_ImportFrom: + w.printImportFrom(n.ImportFrom, indent) + + case *ast.Node_Module: + w.printModule(n.Module, indent) + + case *ast.Node_Name: + w.print(n.Name.Id) + + case *ast.Node_Subscript: + w.printSubscript(n.Subscript, indent) + + default: + panic(n) + + } +} + +func (w *writer) printAnnAssign(aa *ast.AnnAssign, indent int32) { + if aa.Comment != "" { + w.print("# ") + w.print(aa.Comment) + w.print("\n") + w.printIndent(indent) + } + w.printName(aa.Target, indent) + w.print(": ") + w.printNode(aa.Annotation, indent) +} + +func (w *writer) printAssign(a *ast.Assign, indent int32) { + for i, name := range a.Targets { + w.printName(name, indent) + if i != len(a.Targets)-1 { + w.print(", ") + } + } + w.print(" = ") + w.printNode(a.Value, indent) +} + +func (w *writer) printAttribute(a *ast.Attribute, indent int32) { + w.printName(a.Value, indent) + w.print(".") + w.print(a.Attr) +} + +func (w *writer) printCall(c *ast.Call, indent int32) { + w.printNode(c.Func, indent) + w.print("()") +} + +func (w *writer) printClassDef(cd *ast.ClassDef, indent int32) { + for _, node := range cd.DecoratorList { + w.print("@") + w.printNode(node, indent) + w.print("\n") + } + w.print("class ") + w.print(cd.Name) + if len(cd.Bases) > 0 { + w.print("(") + for i, node := range cd.Bases { + w.printNode(node, indent) + if i != len(cd.Bases)-1 { + w.print(", ") + } + } + w.print(")") + } + w.print(":\n") + for i, node := range cd.Body { + w.printIndent(indent + 1) + // A docstring is a string literal that occurs as the first + // statement in a module, function, class, or method + // definition. Such a docstring becomes the __doc__ special + // attribute of that object. + if i == 0 { + if e, ok := node.Node.(*ast.Node_Expr); ok { + if c, ok := e.Expr.Value.Node.(*ast.Node_Constant); ok { + w.print(`"""`) + w.print(c.Constant.Value) + w.print(`"""`) + w.print("\n") + continue + } + } + } + w.printNode(node, indent+1) + w.print("\n") + } +} + +func (w *writer) printConstant(c *ast.Constant, indent int32) { + w.print("\"") + w.print(c.Value) + w.print("\"") +} + +func (w *writer) printComment(c *ast.Comment, indent int32) { + w.print("# ") + w.print(c.Text) + w.print("\n") +} + +func (w *writer) printImport(imp *ast.Import, indent int32) { + w.print("import ") + for i, node := range imp.Names { + w.printNode(node, indent) + if i != len(imp.Names)-1 { + w.print(", ") + } + } + w.print("\n") +} + +func (w *writer) printImportFrom(imp *ast.ImportFrom, indent int32) { + w.print("from ") + w.print(imp.Module) + w.print(" import ") + for i, node := range imp.Names { + w.printNode(node, indent) + if i != len(imp.Names)-1 { + w.print(", ") + } + } + w.print("\n") +} + +func (w *writer) printModule(mod *ast.Module, indent int32) { + for _, node := range mod.Body { + if _, ok := node.Node.(*ast.Node_ClassDef); ok { + w.print("\n\n") + } + w.printNode(node, indent) + } +} + +func (w *writer) printName(n *ast.Name, indent int32) { + w.print(n.Id) +} + +func (w *writer) printSubscript(ss *ast.Subscript, indent int32) { + w.printName(ss.Value, indent) + w.print("[") + w.printNode(ss.Slice, indent) + w.print("]") + +} diff --git a/internal/python/printer/printer_test.go b/internal/python/printer/printer_test.go new file mode 100644 index 0000000000..6237819b95 --- /dev/null +++ b/internal/python/printer/printer_test.go @@ -0,0 +1,190 @@ +package printer + +import ( + "strings" + "testing" + + "github.com/google/go-cmp/cmp" + + "github.com/kyleconroy/sqlc/internal/python/ast" +) + +type testcase struct { + Node *ast.Node + Expected string +} + +func TestPrinter(t *testing.T) { + for name, tc := range map[string]testcase{ + "assign": { + Node: &ast.Node{ + Node: &ast.Node_Assign{ + Assign: &ast.Assign{ + Targets: []*ast.Name{ + {Id: "FICTION"}, + }, + Value: &ast.Node{ + Node: &ast.Node_Constant{ + Constant: &ast.Constant{ + Value: "FICTION", + }, + }, + }, + }, + }, + }, + Expected: `FICTION = "FICTION"`, + }, + "class-base": { + Node: &ast.Node{ + Node: &ast.Node_ClassDef{ + ClassDef: &ast.ClassDef{ + Name: "Foo", + Bases: []*ast.Node{ + { + Node: &ast.Node_Name{ + Name: &ast.Name{Id: "str"}, + }, + }, + { + Node: &ast.Node_Attribute{ + Attribute: &ast.Attribute{ + Value: &ast.Name{Id: "enum"}, + Attr: "Enum", + }, + }, + }, + }, + }, + }, + }, + Expected: `class Foo(str, enum.Enum):`, + }, + "dataclass": { + Node: &ast.Node{ + Node: &ast.Node_ClassDef{ + ClassDef: &ast.ClassDef{ + Name: "Foo", + DecoratorList: []*ast.Node{ + { + Node: &ast.Node_Name{ + Name: &ast.Name{ + Id: "dataclass", + }, + }, + }, + }, + Body: []*ast.Node{ + { + Node: &ast.Node_AnnAssign{ + AnnAssign: &ast.AnnAssign{ + Target: &ast.Name{Id: "bar"}, + Annotation: &ast.Node{ + Node: &ast.Node_Name{ + Name: &ast.Name{Id: "int"}, + }, + }, + }, + }, + }, + { + Node: &ast.Node_AnnAssign{ + AnnAssign: &ast.AnnAssign{ + Target: &ast.Name{Id: "bat"}, + Annotation: &ast.Node{ + Node: &ast.Node_Subscript{ + Subscript: &ast.Subscript{ + Value: &ast.Name{Id: "Optional"}, + Slice: &ast.Node{ + Node: &ast.Node_Name{ + Name: &ast.Name{Id: "int"}, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + Expected: ` +@dataclass +class Foo: + bar: int + bat: Optional[int] +`, + }, + "call": { + Node: &ast.Node{ + Node: &ast.Node_Call{ + Call: &ast.Call{ + Func: &ast.Node{ + Node: &ast.Node_Alias{ + Alias: &ast.Alias{ + Name: "foo", + }, + }, + }, + }, + }, + }, + Expected: `foo()`, + }, + + "import": { + Node: &ast.Node{ + Node: &ast.Node_Import{ + Import: &ast.Import{ + Names: []*ast.Node{ + { + Node: &ast.Node_Alias{ + Alias: &ast.Alias{ + Name: "foo", + }, + }, + }, + }, + }, + }, + }, + Expected: `import foo`, + }, + "import-from": { + Node: &ast.Node{ + Node: &ast.Node_ImportFrom{ + ImportFrom: &ast.ImportFrom{ + Module: "pkg", + Names: []*ast.Node{ + { + Node: &ast.Node_Alias{ + Alias: &ast.Alias{ + Name: "foo", + }, + }, + }, + { + Node: &ast.Node_Alias{ + Alias: &ast.Alias{ + Name: "bar", + }, + }, + }, + }, + }, + }, + }, + Expected: `from pkg import foo, bar`, + }, + } { + tc := tc + t.Run(name, func(t *testing.T) { + result := Print(tc.Node, Options{}) + if diff := cmp.Diff(strings.TrimSpace(tc.Expected), strings.TrimSpace(string(result.Python))); diff != "" { + t.Errorf("print mismatch (-want +got):\n%s", diff) + } + }) + } +} diff --git a/protos/python/ast.proto b/protos/python/ast.proto new file mode 100644 index 0000000000..2f1d8fac7f --- /dev/null +++ b/protos/python/ast.proto @@ -0,0 +1,109 @@ +syntax = "proto3"; + +package ast; + +option go_package = "github.com/kyleconroy/sqlc/internal/python/ast"; + +message Node { + oneof node { + ClassDef class_def = 1 [json_name="ClassDef"]; + Import import = 2 [json_name="Import"]; + ImportFrom import_from = 3 [json_name="ImportFrom"]; + Module module = 4 [json_name="Module"]; + Alias alias = 5 [json_name="Alias"]; + AnnAssign ann_assign = 6 [json_name="AnnAssign"]; + Name name = 7 [json_name="Name"]; + Subscript subscript = 8 [json_name="Subscript"]; + Attribute attribute = 9 [json_name="Attribute"]; + Constant constant = 10 [json_name="Constant"]; + Assign assign = 11 [json_name="Assign"]; + Comment comment = 12 [json_name="Comment"]; + Expr expr = 13 [json_name="Expr"]; + Call call = 14 [json_name="Call"]; + } +} + +message Alias +{ + string name = 1 [json_name="name"]; +} + +message Attribute +{ + Name value = 1 [json_name="value"]; + string attr = 2 [json_name="attr"]; +} + +message AnnAssign +{ + Name target = 1 [json_name="target"]; + Node annotation = 2 [json_name="annotation"]; + int32 simple = 3 [json_name="simple"]; + string Comment = 4 [json_name="comment"]; +} + +message Assign +{ + repeated Name targets = 1 [json_name="targets"]; + Node value = 2 [json_name="value"]; + string Comment = 3 [json_name="comment"]; +} + +message Call +{ + Node func = 1 [json_name="func"]; +} + +message ClassDef +{ + string name = 1 [json_name="name"]; + repeated Node bases = 2 [json_name="bases"]; + repeated Node keywords = 3 [json_name="keywords"]; + repeated Node body = 4 [json_name="body"]; + repeated Node decorator_list = 5 [json_name="decorator_list"]; +} + +// The Python ast module does not parse comments. It's not clear if this is the +// best way to support them in the AST +message Comment +{ + string text = 1 [json_name="text"]; +} + +message Constant +{ + string value = 1 [json_name="value"]; +} + +message Expr +{ + Node value = 1 [json_name="value"]; +} + +message Import +{ + repeated Node names = 1 [json_name="names"]; +} + +message ImportFrom +{ + string module = 1 [json_name="module"]; + repeated Node names = 2 [json_name="names"]; + int32 level = 3 [json_name="level"]; +} + +message Module +{ + repeated Node body = 1 [json_name="body"]; +} + +message Name +{ + string id = 1 [json_name="id"]; +} + +message Subscript +{ + Name value = 1 [json_name="value"]; + Node slice = 2 [json_name="slice"]; +}