github.com/jshiv/can-go@v0.2.1-0.20210224011015-069e90e90bdf/internal/generate/file.go (about) 1 package generate 2 3 import ( 4 "bytes" 5 "fmt" 6 "go/format" 7 "go/types" 8 "path" 9 "strings" 10 11 "github.com/shurcooL/go-goon" 12 "go.einride.tech/can/pkg/descriptor" 13 ) 14 15 type File struct { 16 buf bytes.Buffer 17 err error 18 } 19 20 func NewFile() *File { 21 f := &File{} 22 f.buf.Grow(1e5) // 100K 23 return f 24 } 25 26 func (f *File) Write(p []byte) (int, error) { 27 if f.err != nil { 28 return 0, f.err 29 } 30 n, err := f.buf.Write(p) 31 f.err = err 32 return n, err 33 } 34 35 func (f *File) P(v ...interface{}) { 36 for _, x := range v { 37 _, _ = fmt.Fprint(f, x) 38 } 39 _, _ = fmt.Fprintln(f) 40 } 41 42 func (f *File) Dump(v interface{}) { 43 _, _ = goon.Fdump(f, v) 44 } 45 46 func (f *File) Content() ([]byte, error) { 47 if f.err != nil { 48 return nil, fmt.Errorf("file content: %w", f.err) 49 } 50 formatted, err := format.Source(f.buf.Bytes()) 51 if err != nil { 52 return nil, fmt.Errorf("file content: %s: %w", f.buf.String(), err) 53 } 54 return formatted, nil 55 } 56 57 func Database(d *descriptor.Database) ([]byte, error) { 58 f := NewFile() 59 Package(f, d) 60 Imports(f) 61 for _, m := range d.Messages { 62 MessageType(f, m) 63 for _, s := range m.Signals { 64 if hasCustomType(s) { 65 SignalCustomType(f, m, s) 66 } 67 } 68 MarshalFrame(f, m) 69 UnmarshalFrame(f, m) 70 } 71 if hasSendType(d) { // only code-generate nodes for schemas with send types specified 72 for _, n := range d.Nodes { 73 Node(f, d, n) 74 } 75 } 76 Descriptors(f, d) 77 return f.Content() 78 } 79 80 func Package(f *File, d *descriptor.Database) { 81 packageName := strings.TrimSuffix(path.Base(d.SourceFile), path.Ext(d.SourceFile)) + "can" 82 f.P("// Package ", packageName, " provides primitives for encoding and decoding ", d.Name(), " CAN messages.") 83 f.P("//") 84 f.P("// Source: ", d.SourceFile) 85 f.P("package ", packageName) 86 f.P() 87 } 88 89 func Imports(f *File) { 90 f.P("import (") 91 f.P(`"context"`) 92 f.P(`"fmt"`) 93 f.P(`"net"`) 94 f.P(`"net/http"`) 95 f.P(`"sync"`) 96 f.P(`"time"`) 97 f.P() 98 f.P(`"go.einride.tech/can"`) 99 f.P(`"go.einride.tech/can/pkg/socketcan"`) 100 f.P(`"go.einride.tech/can/pkg/candebug"`) 101 f.P(`"go.einride.tech/can/pkg/canrunner"`) 102 f.P(`"go.einride.tech/can/pkg/descriptor"`) 103 f.P(`"go.einride.tech/can/pkg/generated"`) 104 f.P(`"go.einride.tech/can/pkg/cantext"`) 105 f.P(")") 106 f.P() 107 // we could use goimports for this, but it significantly slows down code generation 108 f.P("// prevent unused imports") 109 f.P("var (") 110 f.P("_ = context.Background") 111 f.P("_ = fmt.Print") 112 f.P("_ = net.Dial") 113 f.P("_ = http.Error") 114 f.P("_ = sync.Mutex{}") 115 f.P("_ = time.Now") 116 f.P("_ = socketcan.Dial") 117 f.P("_ = candebug.ServeMessagesHTTP") 118 f.P("_ = canrunner.Run") 119 f.P(")") 120 f.P() 121 f.P("// Generated code. DO NOT EDIT.") 122 } 123 124 func SignalCustomType(f *File, m *descriptor.Message, s *descriptor.Signal) { 125 f.P("// ", signalType(m, s), " models the ", s.Name, " signal of the ", m.Name, " message.") 126 f.P("type ", signalType(m, s), " ", signalPrimitiveType(s)) 127 f.P() 128 f.P("// Value descriptions for the ", s.Name, " signal of the ", m.Name, " message.") 129 f.P("const (") 130 for _, vd := range s.ValueDescriptions { 131 switch { 132 case s.Length == 1 && vd.Value == 1: 133 f.P(signalType(m, s), "_", vd.Description, " ", signalType(m, s), " = true") 134 case s.Length == 1 && vd.Value == 0: 135 f.P(signalType(m, s), "_", vd.Description, " ", signalType(m, s), " = false") 136 default: 137 f.P(signalType(m, s), "_", vd.Description, " ", signalType(m, s), " = ", vd.Value) 138 } 139 } 140 f.P(")") 141 f.P() 142 f.P("func (v ", signalType(m, s), ") String() string {") 143 if s.Length == 1 { 144 f.P("switch bool(v) {") 145 for _, vd := range s.ValueDescriptions { 146 if vd.Value == 1 { 147 f.P("case true:") 148 } else { 149 f.P("case false:") 150 } 151 f.P(`return "`, vd.Description, `"`) 152 } 153 f.P("}") 154 f.P(`return fmt.Sprintf("`, signalType(m, s), `(%t)", v)`) 155 } else { 156 f.P("switch v {") 157 for _, vd := range s.ValueDescriptions { 158 f.P("case ", vd.Value, ":") 159 f.P(`return "`, vd.Description, `"`) 160 } 161 f.P("default:") 162 f.P(`return fmt.Sprintf("`, signalType(m, s), `(%d)", v)`) 163 f.P("}") 164 } 165 f.P("}") 166 } 167 168 func MessageType(f *File, m *descriptor.Message) { 169 f.P("// ", messageReaderInterface(m), " provides read access to a ", m.Name, " message.") 170 f.P("type ", messageReaderInterface(m), " interface {") 171 for _, s := range m.Signals { 172 if hasPhysicalRepresentation(s) { 173 f.P("// ", s.Name, " returns the physical value of the ", s.Name, " signal.") 174 f.P(s.Name, "() float64") 175 if len(s.ValueDescriptions) > 0 { 176 f.P() 177 f.P("// ", s.Name, " returns the raw (encoded) value of the ", s.Name, " signal.") 178 f.P("Raw", s.Name, "() ", signalType(m, s)) 179 } 180 } else { 181 f.P("// ", s.Name, " returns the value of the ", s.Name, " signal.") 182 f.P(s.Name, "()", signalType(m, s)) 183 } 184 } 185 f.P("}") 186 f.P() 187 f.P("// ", messageWriterInterface(m), " provides write access to a ", m.Name, " message.") 188 f.P("type ", messageWriterInterface(m), " interface {") 189 f.P("// CopyFrom copies all values from ", messageReaderInterface(m), ".") 190 f.P("CopyFrom(", messageReaderInterface(m), ") *", messageStruct(m)) 191 for _, s := range m.Signals { 192 if hasPhysicalRepresentation(s) { 193 f.P("// Set", s.Name, " sets the physical value of the ", s.Name, " signal.") 194 f.P("Set", s.Name, "(float64) *", messageStruct(m)) 195 if len(s.ValueDescriptions) > 0 { 196 f.P() 197 f.P("// SetRaw", s.Name, " sets the raw (encoded) value of the ", s.Name, " signal.") 198 f.P("SetRaw", s.Name, "(", signalType(m, s), ") *", messageStruct(m)) 199 } 200 } else { 201 f.P("// Set", s.Name, " sets the value of the ", s.Name, " signal.") 202 f.P("Set", s.Name, "(", signalType(m, s), ") *", messageStruct(m)) 203 } 204 } 205 f.P("}") 206 f.P() 207 f.P("type ", messageStruct(m), " struct {") 208 for _, s := range m.Signals { 209 f.P(signalField(s), " ", signalType(m, s)) 210 } 211 f.P("}") 212 f.P() 213 f.P("func New", messageStruct(m), "() *", messageStruct(m), " {") 214 f.P("m := &", messageStruct(m), "{}") 215 f.P("m.Reset()") 216 f.P("return m") 217 f.P("}") 218 f.P() 219 f.P("func (m *", messageStruct(m), ") Reset() {") 220 for _, s := range m.Signals { 221 switch { 222 case s.Length == 1 && s.DefaultValue == 1: 223 f.P("m.", signalField(s), " = true") 224 case s.Length == 1: 225 f.P("m.", signalField(s), " = false") 226 default: 227 f.P("m.", signalField(s), " = ", s.DefaultValue) 228 } 229 } 230 f.P("}") 231 f.P() 232 f.P("func (m *", messageStruct(m), ") CopyFrom(o ", messageReaderInterface(m), ") *", messageStruct(m), "{") 233 for _, s := range m.Signals { 234 if hasPhysicalRepresentation(s) { 235 f.P("m.Set", s.Name, "(o.", s.Name, "())") 236 } else { 237 f.P("m.", signalField(s), " = o.", s.Name, "()") 238 } 239 } 240 f.P("return m") 241 f.P("}") 242 f.P() 243 f.P("// Descriptor returns the ", m.Name, " descriptor.") 244 f.P("func (m *", messageStruct(m), ") Descriptor() *descriptor.Message {") 245 f.P("return ", messageDescriptor(m), ".Message") 246 f.P("}") 247 f.P() 248 f.P("// String returns a compact string representation of the message.") 249 f.P("func(m *", messageStruct(m), ") String() string {") 250 f.P("return cantext.MessageString(m)") 251 f.P("}") 252 f.P() 253 for _, s := range m.Signals { 254 if !hasPhysicalRepresentation(s) { 255 f.P("func (m *", messageStruct(m), ") ", s.Name, "() ", signalType(m, s), " {") 256 f.P("return m.", signalField(s)) 257 f.P("}") 258 f.P() 259 f.P("func (m *", messageStruct(m), ") Set", s.Name, "(v ", signalType(m, s), ") *", messageStruct(m), " {") 260 if s.Length == 1 { 261 f.P("m.", signalField(s), " = v") 262 } else { 263 f.P( 264 "m.", signalField(s), " = ", signalType(m, s), "(", 265 signalDescriptor(m, s), ".SaturatedCast", signalSuperType(s), "(", 266 signalPrimitiveSuperType(s), "(v)))", 267 ) 268 } 269 f.P("return m") 270 f.P("}") 271 f.P() 272 continue 273 } 274 f.P("func (m *", messageStruct(m), ") ", s.Name, "() float64 {") 275 f.P("return ", signalDescriptor(m, s), ".ToPhysical(float64(m.", signalField(s), "))") 276 f.P("}") 277 f.P() 278 f.P("func (m *", messageStruct(m), ") Set", s.Name, "(v float64) *", messageStruct(m), " {") 279 f.P("m.", signalField(s), " = ", signalType(m, s), "(", signalDescriptor(m, s), ".FromPhysical(v))") 280 f.P("return m") 281 f.P("}") 282 f.P() 283 if len(s.ValueDescriptions) > 0 { 284 f.P("func (m *", messageStruct(m), ") Raw", s.Name, "() ", signalType(m, s), " {") 285 f.P("return m.", signalField(s)) 286 f.P("}") 287 f.P() 288 f.P("func (m *", messageStruct(m), ") SetRaw", s.Name, "(v ", signalType(m, s), ") *", messageStruct(m), "{") 289 f.P( 290 "m.", signalField(s), " = ", signalType(m, s), "(", 291 signalDescriptor(m, s), ".SaturatedCast", signalSuperType(s), "(", 292 signalPrimitiveSuperType(s), "(v)))", 293 ) 294 f.P("return m") 295 f.P("}") 296 f.P() 297 } 298 } 299 } 300 301 func Descriptors(f *File, d *descriptor.Database) { 302 f.P("// Nodes returns the ", d.Name(), " node descriptors.") 303 f.P("func Nodes() *NodesDescriptor {") 304 f.P("return nd") 305 f.P("}") 306 f.P() 307 f.P("// NodesDescriptor contains all ", d.Name(), " node descriptors.") 308 f.P("type NodesDescriptor struct{") 309 for _, n := range d.Nodes { 310 f.P(n.Name, " *descriptor.Node") 311 } 312 f.P("}") 313 f.P() 314 f.P("// Messages returns the ", d.Name(), " message descriptors.") 315 f.P("func Messages() *MessagesDescriptor {") 316 f.P("return md") 317 f.P("}") 318 f.P() 319 f.P("// MessagesDescriptor contains all ", d.Name(), " message descriptors.") 320 f.P("type MessagesDescriptor struct{") 321 for _, m := range d.Messages { 322 f.P(m.Name, " *", m.Name, "Descriptor") 323 } 324 f.P("}") 325 f.P() 326 f.P("// UnmarshalFrame unmarshals the provided ", d.Name(), " CAN frame.") 327 f.P("func (md *MessagesDescriptor) UnmarshalFrame(f can.Frame) (generated.Message, error) {") 328 f.P("switch f.ID {") 329 for _, m := range d.Messages { 330 f.P("case md.", m.Name, ".ID:") 331 f.P("var msg ", messageStruct(m)) 332 f.P("if err := msg.UnmarshalFrame(f); err != nil {") 333 f.P(`return nil, fmt.Errorf("unmarshal `, d.Name(), ` frame: %w", err)`) 334 f.P("}") 335 f.P("return &msg, nil") 336 } 337 f.P("default:") 338 f.P(`return nil, fmt.Errorf("unmarshal `, d.Name(), ` frame: ID not in database: %d", f.ID)`) 339 f.P("}") 340 f.P("}") 341 f.P() 342 for _, m := range d.Messages { 343 f.P("type ", m.Name, "Descriptor struct{") 344 f.P("*descriptor.Message") 345 for _, s := range m.Signals { 346 f.P(s.Name, " *descriptor.Signal") 347 } 348 f.P("}") 349 f.P() 350 } 351 f.P("// Database returns the ", d.Name(), " database descriptor.") 352 f.P("func (md *MessagesDescriptor) Database() *descriptor.Database {") 353 f.P("return d") 354 f.P("}") 355 f.P() 356 f.P("var nd = &NodesDescriptor{") 357 for ni, n := range d.Nodes { 358 f.P(n.Name, ": d.Nodes[", ni, "],") 359 } 360 f.P("}") 361 f.P() 362 f.P("var md = &MessagesDescriptor{") 363 for mi, m := range d.Messages { 364 f.P(m.Name, ": &", m.Name, "Descriptor{") 365 f.P("Message: d.Messages[", mi, "],") 366 for si, s := range m.Signals { 367 f.P(s.Name, ": d.Messages[", mi, "].Signals[", si, "],") 368 } 369 f.P("},") 370 } 371 f.P("}") 372 f.P() 373 f.P("var d = ") 374 f.Dump(d) 375 f.P() 376 } 377 378 func MarshalFrame(f *File, m *descriptor.Message) { 379 f.P("// Frame returns a CAN frame representing the message.") 380 f.P("func (m *", messageStruct(m), ") Frame() can.Frame {") 381 f.P("md := ", messageDescriptor(m)) 382 f.P("f := can.Frame{ID: md.ID, IsExtended: md.IsExtended, Length: md.Length}") 383 for _, s := range m.Signals { 384 if s.IsMultiplexed { 385 continue 386 } 387 f.P( 388 "md.", s.Name, ".Marshal", signalSuperType(s), 389 "(&f.Data, ", signalPrimitiveSuperType(s), "(m.", signalField(s), "))", 390 ) 391 } 392 if mux, ok := m.MultiplexerSignal(); ok { 393 for _, s := range m.Signals { 394 if !s.IsMultiplexed { 395 continue 396 } 397 f.P("if m.", signalField(mux), " == ", s.MultiplexerValue, " {") 398 f.P( 399 "md.", s.Name, ".Marshal", signalSuperType(s), "(&f.Data, ", signalPrimitiveSuperType(s), 400 "(m.", signalField(s), "))", 401 ) 402 f.P("}") 403 } 404 } 405 f.P("return f") 406 f.P("}") 407 f.P() 408 f.P("// MarshalFrame encodes the message as a CAN frame.") 409 f.P("func (m *", messageStruct(m), ") MarshalFrame() (can.Frame, error) {") 410 f.P("return m.Frame(), nil") 411 f.P("}") 412 f.P() 413 } 414 415 func UnmarshalFrame(f *File, m *descriptor.Message) { 416 f.P("// UnmarshalFrame decodes the message from a CAN frame.") 417 f.P("func (m *", messageStruct(m), ") UnmarshalFrame(f can.Frame) error {") 418 f.P("md := ", messageDescriptor(m)) 419 // generate frame checks 420 id := func(isExtended bool) string { 421 if isExtended { 422 return "extended ID" 423 } 424 return "standard ID" 425 } 426 f.P("switch {") 427 f.P("case f.ID != md.ID:") 428 f.P(`return fmt.Errorf(`) 429 f.P(`"unmarshal `, m.Name, `: expects ID `, m.ID, ` (got %s with ID %d)", f.String(), f.ID,`) 430 f.P(`)`) 431 f.P("case f.Length != md.Length:") 432 f.P(`return fmt.Errorf(`) 433 f.P(`"unmarshal `, m.Name, `: expects length `, m.Length, ` (got %s with length %d)", f.String(), f.Length,`) 434 f.P(`)`) 435 f.P("case f.IsRemote:") 436 f.P(`return fmt.Errorf(`) 437 f.P(`"unmarshal `, m.Name, `: expects non-remote frame (got remote frame %s)", f.String(),`) 438 f.P(`)`) 439 f.P("case f.IsExtended != md.IsExtended:") 440 f.P(`return fmt.Errorf(`) 441 f.P(`"unmarshal `, m.Name, `: expects `, id(m.IsExtended), ` (got %s with `, id(!m.IsExtended), `)", f.String(),`) 442 f.P(`)`) 443 f.P("}") 444 if len(m.Signals) == 0 { 445 f.P("return nil") 446 f.P("}") 447 return 448 } 449 // generate non-multiplexed signal unmarshaling 450 for _, s := range m.Signals { 451 if s.IsMultiplexed { 452 continue 453 } 454 f.P("m.", signalField(s), " = ", signalType(m, s), "(md.", s.Name, ".Unmarshal", signalSuperType(s), "(f.Data))") 455 } 456 // generate multiplexed signal unmarshaling 457 if mux, ok := m.MultiplexerSignal(); ok { 458 for _, s := range m.Signals { 459 if !s.IsMultiplexed { 460 continue 461 } 462 f.P("if m.", signalField(mux), " == ", s.MultiplexerValue, " {") 463 f.P("m.", signalField(s), " = ", signalType(m, s), "(md.", s.Name, ".Unmarshal", signalSuperType(s), "(f.Data))") 464 f.P("}") 465 } 466 } 467 f.P("return nil") 468 f.P("}") 469 f.P() 470 } 471 472 func Node(f *File, d *descriptor.Database, n *descriptor.Node) { 473 rxMessages := collectRxMessages(d, n) 474 txMessages := collectTxMessages(d, n) 475 f.P("type ", nodeInterface(n), " interface {") 476 f.P("sync.Locker") 477 f.P("Tx() ", txGroupInterface(n)) 478 f.P("Rx() ", rxGroupInterface(n)) 479 f.P("Run(ctx context.Context) error") 480 f.P("}") 481 f.P() 482 f.P("type ", rxGroupInterface(n), " interface {") 483 f.P("http.Handler // for debugging") 484 for _, m := range rxMessages { 485 f.P(m.Name, "() ", rxMessageInterface(n, m)) 486 } 487 f.P("}") 488 f.P() 489 f.P("type ", txGroupInterface(n), " interface {") 490 f.P("http.Handler // for debugging") 491 for _, m := range txMessages { 492 f.P(m.Name, "() ", txMessageInterface(n, m)) 493 } 494 f.P("}") 495 f.P() 496 for _, m := range rxMessages { 497 f.P("type ", rxMessageInterface(n, m), " interface {") 498 f.P(messageReaderInterface(m)) 499 f.P("ReceiveTime() time.Time") 500 f.P("SetAfterReceiveHook(h func(context.Context) error)") 501 f.P("}") 502 f.P() 503 } 504 for _, m := range txMessages { 505 f.P("type ", txMessageInterface(n, m), " interface {") 506 f.P(messageReaderInterface(m)) 507 f.P(messageWriterInterface(m)) 508 f.P("TransmitTime() time.Time") 509 f.P("Transmit(ctx context.Context) error") 510 f.P("SetBeforeTransmitHook(h func(context.Context) error)") 511 if m.SendType == descriptor.SendTypeCyclic { 512 f.P("// SetCyclicTransmissionEnabled enables/disables cyclic transmission.") 513 f.P("SetCyclicTransmissionEnabled(bool)") 514 f.P("// IsCyclicTransmissionEnabled returns whether cyclic transmission is enabled/disabled.") 515 f.P("IsCyclicTransmissionEnabled() bool") 516 } 517 f.P("}") 518 f.P() 519 } 520 f.P("type ", nodeStruct(n), " struct {") 521 f.P("sync.Mutex // protects all node state") 522 f.P("network string") 523 f.P("address string") 524 f.P("rx ", rxGroupStruct(n)) 525 f.P("tx ", txGroupStruct(n)) 526 f.P("}") 527 f.P() 528 f.P("var _ ", nodeInterface(n), " = &", nodeStruct(n), "{}") 529 f.P("var _ canrunner.Node = &", nodeStruct(n), "{}") 530 f.P() 531 f.P("func New", nodeInterface(n), "(network, address string) ", nodeInterface(n), " {") 532 f.P("n := &", nodeStruct(n), "{network: network, address: address}") 533 f.P("n.rx.parentMutex = &n.Mutex") 534 f.P("n.tx.parentMutex = &n.Mutex") 535 for _, m := range rxMessages { 536 f.P("n.rx.", messageField(m), ".init()") 537 f.P("n.rx.", messageField(m), ".Reset()") 538 } 539 for _, m := range txMessages { 540 f.P("n.tx.", messageField(m), ".init()") 541 f.P("n.tx.", messageField(m), ".Reset()") 542 } 543 f.P("return n") 544 f.P("}") 545 f.P() 546 f.P("func (n *", nodeStruct(n), ") Run(ctx context.Context) error {") 547 f.P("return canrunner.Run(ctx, n)") 548 f.P("}") 549 f.P() 550 f.P("func (n *", nodeStruct(n), ") Rx() ", rxGroupInterface(n), " {") 551 f.P("return &n.rx") 552 f.P("}") 553 f.P() 554 f.P("func (n *", nodeStruct(n), ") Tx() ", txGroupInterface(n), " {") 555 f.P("return &n.tx") 556 f.P("}") 557 f.P() 558 f.P("type ", rxGroupStruct(n), " struct {") 559 f.P("parentMutex *sync.Mutex") 560 for _, m := range rxMessages { 561 f.P(messageField(m), " ", rxMessageStruct(n, m)) 562 } 563 f.P("}") 564 f.P() 565 f.P("var _ ", rxGroupInterface(n), " = &", rxGroupStruct(n), "{}") 566 f.P() 567 f.P("func (rx *", rxGroupStruct(n), ") ServeHTTP(w http.ResponseWriter, r *http.Request) {") 568 f.P("rx.parentMutex.Lock()") 569 f.P("defer rx.parentMutex.Unlock()") 570 f.P("candebug.ServeMessagesHTTP(w, r, []generated.Message{") 571 for _, m := range rxMessages { 572 f.P("&rx.", messageField(m), ",") 573 } 574 f.P("})") 575 f.P("}") 576 f.P() 577 for _, m := range rxMessages { 578 f.P("func (rx *", rxGroupStruct(n), ") ", m.Name, "() ", rxMessageInterface(n, m), " {") 579 f.P("return &rx.", messageField(m)) 580 f.P("}") 581 f.P() 582 } 583 f.P() 584 f.P("type ", txGroupStruct(n), " struct {") 585 f.P("parentMutex *sync.Mutex") 586 for _, m := range txMessages { 587 f.P(messageField(m), " ", txMessageStruct(n, m)) 588 } 589 f.P("}") 590 f.P() 591 f.P("var _ ", txGroupInterface(n), " = &", txGroupStruct(n), "{}") 592 f.P() 593 f.P("func (tx *", txGroupStruct(n), ") ServeHTTP(w http.ResponseWriter, r *http.Request) {") 594 f.P("tx.parentMutex.Lock()") 595 f.P("defer tx.parentMutex.Unlock()") 596 f.P("candebug.ServeMessagesHTTP(w, r, []generated.Message{") 597 for _, m := range txMessages { 598 f.P("&tx.", messageField(m), ",") 599 } 600 f.P("})") 601 f.P("}") 602 f.P() 603 for _, m := range txMessages { 604 f.P("func (tx *", txGroupStruct(n), ") ", m.Name, "() ", txMessageInterface(n, m), " {") 605 f.P("return &tx.", messageField(m)) 606 f.P("}") 607 f.P() 608 } 609 f.P() 610 f.P("func (n *", nodeStruct(n), ") Descriptor() *descriptor.Node {") 611 f.P("return ", nodeDescriptor(n)) 612 f.P("}") 613 f.P() 614 f.P("func (n *", nodeStruct(n), ") Connect() (net.Conn, error) {") 615 f.P("return socketcan.Dial(n.network, n.address)") 616 f.P("}") 617 f.P() 618 f.P("func (n *", nodeStruct(n), ") ReceivedMessage(id uint32) (canrunner.ReceivedMessage, bool) {") 619 f.P("switch id {") 620 for _, m := range rxMessages { 621 f.P("case ", m.ID, ":") 622 f.P("return &n.rx.", messageField(m), ", true") 623 } 624 f.P("default:") 625 f.P("return nil, false") 626 f.P("}") 627 f.P("}") 628 f.P() 629 f.P("func (n *", nodeStruct(n), ") TransmittedMessages() []canrunner.TransmittedMessage {") 630 f.P("return []canrunner.TransmittedMessage{") 631 for _, m := range txMessages { 632 f.P("&n.tx.", messageField(m), ",") 633 } 634 f.P("}") 635 f.P("}") 636 f.P() 637 for _, m := range rxMessages { 638 f.P("type ", rxMessageStruct(n, m), " struct {") 639 f.P(messageStruct(m)) 640 f.P("receiveTime time.Time") 641 f.P("afterReceiveHook func(context.Context) error") 642 f.P("}") 643 f.P() 644 f.P("func (m *", rxMessageStruct(n, m), ") init() {") 645 f.P("m.afterReceiveHook = func(context.Context) error { return nil }") 646 f.P("}") 647 f.P() 648 f.P("func (m *", rxMessageStruct(n, m), ") SetAfterReceiveHook(h func(context.Context) error) {") 649 f.P("m.afterReceiveHook = h") 650 f.P("}") 651 f.P() 652 f.P("func (m *", rxMessageStruct(n, m), ") AfterReceiveHook() func(context.Context) error {") 653 f.P("return m.afterReceiveHook") 654 f.P("}") 655 f.P() 656 f.P("func (m *", rxMessageStruct(n, m), ") ReceiveTime() time.Time {") 657 f.P("return m.receiveTime") 658 f.P("}") 659 f.P() 660 f.P("func (m *", rxMessageStruct(n, m), ") SetReceiveTime(t time.Time) {") 661 f.P("m.receiveTime = t") 662 f.P("}") 663 f.P() 664 f.P("var _ canrunner.ReceivedMessage = &", rxMessageStruct(n, m), "{}") 665 f.P() 666 } 667 for _, m := range txMessages { 668 f.P("type ", txMessageStruct(n, m), " struct {") 669 f.P(messageStruct(m)) 670 f.P("transmitTime time.Time") 671 f.P("beforeTransmitHook func(context.Context) error") 672 f.P("isCyclicEnabled bool") 673 f.P("wakeUpChan chan struct{}") 674 f.P("transmitEventChan chan struct{}") 675 f.P("}") 676 f.P() 677 f.P("var _ ", txMessageInterface(n, m), " = &", txMessageStruct(n, m), "{}") 678 f.P("var _ canrunner.TransmittedMessage = &", txMessageStruct(n, m), "{}") 679 f.P() 680 f.P("func (m *", txMessageStruct(n, m), ") init() {") 681 f.P("m.beforeTransmitHook = func(context.Context) error { return nil }") 682 f.P("m.wakeUpChan = make(chan struct{}, 1)") 683 f.P("m.transmitEventChan = make(chan struct{})") 684 f.P("}") 685 f.P() 686 f.P("func (m *", txMessageStruct(n, m), ") SetBeforeTransmitHook(h func(context.Context) error) {") 687 f.P("m.beforeTransmitHook = h") 688 f.P("}") 689 f.P() 690 f.P("func (m *", txMessageStruct(n, m), ") BeforeTransmitHook() func(context.Context) error {") 691 f.P("return m.beforeTransmitHook") 692 f.P("}") 693 f.P() 694 f.P("func (m *", txMessageStruct(n, m), ") TransmitTime() time.Time {") 695 f.P("return m.transmitTime") 696 f.P("}") 697 f.P() 698 f.P("func (m *", txMessageStruct(n, m), ") SetTransmitTime(t time.Time) {") 699 f.P("m.transmitTime = t") 700 f.P("}") 701 f.P() 702 f.P("func (m *", txMessageStruct(n, m), ") IsCyclicTransmissionEnabled() bool {") 703 f.P("return m.isCyclicEnabled") 704 f.P("}") 705 f.P() 706 f.P("func (m *", txMessageStruct(n, m), ") SetCyclicTransmissionEnabled(b bool) {") 707 f.P("m.isCyclicEnabled = b") 708 f.P("select {") 709 f.P("case m.wakeUpChan <-struct{}{}:") 710 f.P("default:") 711 f.P("}") 712 f.P("}") 713 f.P() 714 f.P("func (m *", txMessageStruct(n, m), ") WakeUpChan() <-chan struct{} {") 715 f.P("return m.wakeUpChan") 716 f.P("}") 717 f.P() 718 f.P("func (m *", txMessageStruct(n, m), ") Transmit(ctx context.Context) error {") 719 f.P("select {") 720 f.P("case m.transmitEventChan <- struct{}{}:") 721 f.P("return nil") 722 f.P("case <-ctx.Done():") 723 f.P(`return fmt.Errorf("event-triggered transmit of `, m.Name, `: %w", ctx.Err())`) 724 f.P("}") 725 f.P("}") 726 f.P() 727 f.P("func (m *", txMessageStruct(n, m), ") TransmitEventChan() <-chan struct{} {") 728 f.P("return m.transmitEventChan") 729 f.P("}") 730 f.P() 731 f.P("var _ canrunner.TransmittedMessage = &", txMessageStruct(n, m), "{}") 732 f.P() 733 } 734 } 735 736 func txGroupInterface(n *descriptor.Node) string { 737 return n.Name + "_Tx" 738 } 739 740 func txGroupStruct(n *descriptor.Node) string { 741 return "xxx_" + n.Name + "_Tx" 742 } 743 744 func rxGroupInterface(n *descriptor.Node) string { 745 return n.Name + "_Rx" 746 } 747 748 func rxGroupStruct(n *descriptor.Node) string { 749 return "xxx_" + n.Name + "_Rx" 750 } 751 752 func rxMessageInterface(n *descriptor.Node, m *descriptor.Message) string { 753 return n.Name + "_Rx_" + m.Name 754 } 755 756 func rxMessageStruct(n *descriptor.Node, m *descriptor.Message) string { 757 return "xxx_" + n.Name + "_Rx_" + m.Name 758 } 759 760 func txMessageInterface(n *descriptor.Node, m *descriptor.Message) string { 761 return n.Name + "_Tx_" + m.Name 762 } 763 764 func txMessageStruct(n *descriptor.Node, m *descriptor.Message) string { 765 return "xxx_" + n.Name + "_Tx_" + m.Name 766 } 767 768 func collectTxMessages(d *descriptor.Database, n *descriptor.Node) []*descriptor.Message { 769 tx := make([]*descriptor.Message, 0, len(d.Messages)) 770 for _, m := range d.Messages { 771 if m.SenderNode == n.Name && m.SendType != descriptor.SendTypeNone { 772 tx = append(tx, m) 773 } 774 } 775 return tx 776 } 777 778 func collectRxMessages(d *descriptor.Database, n *descriptor.Node) []*descriptor.Message { 779 rx := make([]*descriptor.Message, 0, len(d.Messages)) 780 Loop: 781 for _, m := range d.Messages { 782 for _, s := range m.Signals { 783 for _, node := range s.ReceiverNodes { 784 if node != n.Name { 785 continue 786 } 787 rx = append(rx, m) 788 continue Loop 789 } 790 } 791 } 792 return rx 793 } 794 795 func hasPhysicalRepresentation(s *descriptor.Signal) bool { 796 hasScale := s.Scale != 0 && s.Scale != 1 797 hasOffset := s.Offset != 0 798 hasRange := s.Min != 0 || s.Max != 0 799 var hasConstrainedRange bool 800 if s.IsSigned { 801 hasConstrainedRange = s.Min > float64(s.MinSigned()) || s.Max < float64(s.MaxSigned()) 802 } else { 803 hasConstrainedRange = s.Min > 0 || s.Max < float64(s.MaxUnsigned()) 804 } 805 return hasScale || hasOffset || hasRange && hasConstrainedRange 806 } 807 808 func hasCustomType(s *descriptor.Signal) bool { 809 return len(s.ValueDescriptions) > 0 810 } 811 812 func hasSendType(d *descriptor.Database) bool { 813 for _, m := range d.Messages { 814 if m.SendType != descriptor.SendTypeNone { 815 return true 816 } 817 } 818 return false 819 } 820 821 func signalType(m *descriptor.Message, s *descriptor.Signal) string { 822 if hasCustomType(s) { 823 return m.Name + "_" + s.Name 824 } 825 return signalPrimitiveType(s).String() 826 } 827 828 func signalPrimitiveType(s *descriptor.Signal) types.Type { 829 var t types.BasicKind 830 switch { 831 case s.Length == 1: 832 t = types.Bool 833 case s.Length <= 8 && s.IsSigned: 834 t = types.Int8 835 case s.Length <= 8: 836 t = types.Uint8 837 case s.Length <= 16 && s.IsSigned: 838 t = types.Int16 839 case s.Length <= 16: 840 t = types.Uint16 841 case s.Length <= 32 && s.IsSigned: 842 t = types.Int32 843 case s.Length <= 32: 844 t = types.Uint32 845 case s.Length <= 64 && s.IsSigned: 846 t = types.Int64 847 default: 848 t = types.Uint64 849 } 850 return types.Typ[t] 851 } 852 853 func signalPrimitiveSuperType(s *descriptor.Signal) types.Type { 854 var t types.BasicKind 855 switch { 856 case s.Length == 1: 857 t = types.Bool 858 case s.IsSigned: 859 t = types.Int64 860 default: 861 t = types.Uint64 862 } 863 return types.Typ[t] 864 } 865 866 func signalSuperType(s *descriptor.Signal) string { 867 switch { 868 case s.Length == 1: 869 return "Bool" 870 case s.IsSigned: 871 return "Signed" 872 default: 873 return "Unsigned" 874 } 875 } 876 877 func nodeInterface(n *descriptor.Node) string { 878 return n.Name 879 } 880 881 func nodeStruct(n *descriptor.Node) string { 882 return "xxx_" + n.Name 883 } 884 885 func messageStruct(m *descriptor.Message) string { 886 return m.Name 887 } 888 889 func messageReaderInterface(m *descriptor.Message) string { 890 return m.Name + "Reader" 891 } 892 893 func messageWriterInterface(m *descriptor.Message) string { 894 return m.Name + "Writer" 895 } 896 897 func messageField(m *descriptor.Message) string { 898 return "xxx_" + m.Name 899 } 900 901 func signalField(s *descriptor.Signal) string { 902 return "xxx_" + s.Name 903 } 904 905 func nodeDescriptor(n *descriptor.Node) string { 906 return "Nodes()." + n.Name 907 } 908 909 func messageDescriptor(m *descriptor.Message) string { 910 return "Messages()." + m.Name 911 } 912 913 func signalDescriptor(m *descriptor.Message, s *descriptor.Signal) string { 914 return messageDescriptor(m) + "." + s.Name 915 }