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