code: func generateMessage(ctx *context, w io.Writer, msg *Message) {
  	name := camelCaseName(msg.Name)
  
  	logf(" writing message %q (%s) with %d fields", msg.Name, name, len(msg.Fields))
  
  	// generate struct comment
  	generateComment(ctx, w, name, msg.Name, "message")
  
  	// generate struct definition
  	fmt.Fprintf(w, "type %s struct {", name)
  
  	msgType := otherMessage
  	wasClientIndex := false
  
  	// generate struct fields
  	n := 0
  	for i, field := range msg.Fields {
  		if i == 1 {
  			if field.Name == clientIndexField {
  				// "client_index" as the second member,
  				// this might be an event message or a request
  				msgType = eventMessage
  				wasClientIndex = true
  			} else if field.Name == contextField {
  				// reply needs "context" as the second member
  				msgType = replyMessage
  			}
  		} else if i == 2 {
  			if wasClientIndex && field.Name == contextField {
  				// request needs "client_index" as the second member
  				// and "context" as the third member
  				msgType = requestMessage
  			}
  		}
  
  		// skip internal fields
  		switch strings.ToLower(field.Name) {
  		case crcField, msgIdField:
  			continue
  		case clientIndexField, contextField:
  			if n == 0 {
  				continue
  			}
  		}
  		n++
  		if n == 1 {
  			fmt.Fprintln(w)
  		}
  
  		generateField(ctx, w, msg.Fields, i)
  	}
  
  	// generate end of the struct
  	fmt.Fprintln(w, "}")
  
  	// generate name getter
  	generateMessageNameGetter(w, name, msg.Name)
  
  	// generate CRC getter
  	generateCrcGetter(w, name, msg.CRC)
  
  	// generate message type getter method
  	generateMessageTypeGetter(w, name, msgType)
  
  	fmt.Fprintln(w)
  }
docs: // generateMessage writes generated code for the message into w