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  }