Commit ff786dd0 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 368f5366
...@@ -23,7 +23,11 @@ package neo ...@@ -23,7 +23,11 @@ package neo
// This file defines everything that relates to messages on the wire. // This file defines everything that relates to messages on the wire.
// In particular every type that is included in a message is defined here as well. // In particular every type that is included in a message is defined here as well.
// XXX neo:proto justtype //
// By default a structure defined in this file becomes a separate network message.
// If a structure is defined only to represent basic type that is included in
// several messages and does not itself denote a separate message, its
// definition is prefixed with `//neo:proto typeonly` comment.
// XXX neo:proto answerto x? (btw just needs "answer" flag) // XXX neo:proto answerto x? (btw just needs "answer" flag)
// TODO regroup messages definitions to stay more close to 1 communication topic // TODO regroup messages definitions to stay more close to 1 communication topic
...@@ -256,7 +260,7 @@ func float64_NEODecode(b []byte) float64 { ...@@ -256,7 +260,7 @@ func float64_NEODecode(b []byte) float64 {
} }
// NodeInfo is information about a node // NodeInfo is information about a node
// FIXME not pkt //neo:proto typeonly
type NodeInfo struct { type NodeInfo struct {
Type NodeType Type NodeType
Addr Address // serving address Addr Address // serving address
...@@ -265,13 +269,13 @@ type NodeInfo struct { ...@@ -265,13 +269,13 @@ type NodeInfo struct {
IdTimestamp float64 // FIXME clarify semantic where it is used IdTimestamp float64 // FIXME clarify semantic where it is used
} }
// FIXME not pkt //neo:proto typeonly
type CellInfo struct { type CellInfo struct {
UUID NodeUUID UUID NodeUUID
State CellState State CellState
} }
// FIXME not pkt //neo:proto typeonly
type RowInfo struct { type RowInfo struct {
Offset uint32 // PNumber XXX -> Pid Offset uint32 // PNumber XXX -> Pid
CellList []CellInfo CellList []CellInfo
......
...@@ -144,7 +144,7 @@ func loadPkg(pkgPath string, sources ...string) *types.Package { ...@@ -144,7 +144,7 @@ func loadPkg(pkgPath string, sources ...string) *types.Package {
// parse // parse
for _, src := range sources { for _, src := range sources {
f, err := parser.ParseFile(fset, src, nil, 0) f, err := parser.ParseFile(fset, src, nil, parser.ParseComments)
if err != nil { if err != nil {
log.Fatalf("parse: %v", err) log.Fatalf("parse: %v", err)
} }
...@@ -165,6 +165,39 @@ func loadPkg(pkgPath string, sources ...string) *types.Package { ...@@ -165,6 +165,39 @@ func loadPkg(pkgPath string, sources ...string) *types.Package {
return pkg return pkg
} }
// `//neo:proto ...` annotations
type Annotation struct {
typeonly bool
}
// parse checks doc for specific comment annotations and, if present, loads them.
func (a *Annotation) parse(doc *ast.CommentGroup) {
if doc == nil {
return // for many types .Doc = nil if there is no comments
}
for _, comment := range doc.List {
cpos := pos(comment)
if !(cpos.Column == 1 && strings.HasPrefix(comment.Text, "//neo:proto ")) {
continue
}
__ := strings.SplitN(comment.Text, " ", 2)
arg := __[1]
switch arg {
case "typeonly":
if a.typeonly {
log.Fatalf("%v: duplicate typeonly", cpos)
}
a.typeonly = true
default:
log.Fatalf("%v: unknown neo:proto directive %q", cpos, arg)
}
}
}
func main() { func main() {
var err error var err error
...@@ -206,29 +239,41 @@ import ( ...@@ -206,29 +239,41 @@ import (
//ast.Print(fset, gendecl) //ast.Print(fset, gendecl)
//continue //continue
// `//neo:proto ...` annotations for whole decl
// (e.g. <here> type ( t1 struct{...}; t2 struct{...} )
declAnnotation := Annotation{}
declAnnotation.parse(gendecl.Doc)
for _, spec := range gendecl.Specs { for _, spec := range gendecl.Specs {
typespec := spec.(*ast.TypeSpec) // must be because tok = TYPE typespec := spec.(*ast.TypeSpec) // must be because tok = TYPE
typename := typespec.Name.Name typename := typespec.Name.Name
switch typespec.Type.(type) { // we are only interested in struct types
default: if _, ok := typespec.Type.(*ast.StructType); !ok {
// we are only interested in struct types
continue continue
}
case *ast.StructType: // `//neo:proto ...` annotation for this particular type
fmt.Fprintf(&buf, "// %d. %s\n\n", msgCode, typename) specAnnotation := declAnnotation // inheriting from decl
specAnnotation.parse(typespec.Doc)
buf.emit("func (*%s) neoMsgCode() uint16 {", typename) // type only -> don't generate message interface for it
buf.emit("return %d", msgCode) if specAnnotation.typeonly {
buf.emit("}\n") continue
}
buf.WriteString(generateCodecCode(typespec, &sizer{})) fmt.Fprintf(&buf, "// %d. %s\n\n", msgCode, typename)
buf.WriteString(generateCodecCode(typespec, &encoder{}))
buf.WriteString(generateCodecCode(typespec, &decoder{}))
msgTypeRegistry[msgCode] = typename buf.emit("func (*%s) neoMsgCode() uint16 {", typename)
msgCode++ buf.emit("return %d", msgCode)
} buf.emit("}\n")
buf.WriteString(generateCodecCode(typespec, &sizer{}))
buf.WriteString(generateCodecCode(typespec, &encoder{}))
buf.WriteString(generateCodecCode(typespec, &decoder{}))
msgTypeRegistry[msgCode] = typename
msgCode++
} }
} }
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment