bebop

package module
v0.6.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 5, 2024 License: Apache-2.0 Imports: 14 Imported by: 2

README

bebop

Go Reference

bebop is a bebop parser written in Go, for generating Go code.

bebop can read .bop files and output .go files representing them:

mybebop.bop:

struct Foo {
    Bar bar;
}

message Bar {
    1 -> float64 x;
    2 -> float64 y;
    3 -> float64 z;
}
package main

import (
    "github.com/200sc/bebop"
)

func main() {
    f, _ := os.Open("mybebop.bop")
    defer f.Close()
    bopf, _ := bebop.ReadFile(f)
    out, _ := os.Create("mybebop.go")
    defer out.Close()
    settings := bebop.GenerateSettings{
        PackageName: "mybebop",
    }
    bopf.Generate(out, settings)
}

These files can then be used to encode and decode their represented records:

package server

import (
    "github.com/my/project/mybebop"
    "net"
)

func sendFoo(cn net.Conn) (success bool) {
    fooReq := mybebop.FooRequest{
        Bar: "buzz",
    }
    if err := fooReq.EncodeBebop(cn); err != nil {
        // ...
    }
    fooResp := mybebop.FooResponse{}
    if err := fooResp.DecodeBebop(cn); err != nil {
        // ...
    }
    return fooResp.Success
}

bebobc-go

At main/bebobc-go there is a cli utility to take .bop files and produce .go files from them, what is effectively a little more sophisticated version of the first example in this document.

bebopfmt

At main/bebopfmt there is a cli utility to format and rewrite bop files. It takes in a -w argument to rewrite files in place, and accepts both directories and individual filepaths.

Known limitations

The following is a list of known issues with the current version of the project, ordered by approximate priority for addressing them.

  • We should be able to generate server code with handlers given all valid messages have op codes.

  • Tokenization and parsing could attempt corrective fixes to be able to report more than one error.

  • There are several incompatibilities between this compiler and the original compiler. These incompatibilities are documented (see testdata/incompatible), but we should attempt to resolve them. Trivially resolvable incompatibilities have been resolved already, remaining notes should involve raising upstream issues.

Credit

Original bebop compiler (C#, Typescript, ...): https://github.com/RainwayApp/bebop

In addition to defining the spec this package follows, most initial testdata was taken from the above project.

Documentation

Overview

Package bebop provides structures, tokenizing, parsing, and code generation for the bebop file type

Index

Constants

View Source
const Version = "v0.6.2"

Version is the library version. Should be used by CLI tools when passed a '--version' flag.

Variables

This section is empty.

Functions

func Format added in v0.0.6

func Format(r io.Reader, out io.Writer) error

Format reads a .bop file from r and writes out a formatted version of that file to out.

Types

type Const added in v0.1.4

type Const struct {
	// Consts do not support map or array (or record) types
	SimpleType string
	Comment    string
	Name       string
	Value      string
}

A const is a simple type - value pair that is compiled as a constant into generated code.

func (Const) Generate added in v0.1.4

func (con Const) Generate(w io.Writer, settings GenerateSettings)

type Enum

type Enum struct {
	Name    string
	Comment string
	Options []EnumOption
	// Namespace is only provided for imported types, and only
	// used in code generation.
	Namespace string
	// SimpleType is an integer or unsigned integer type. If not
	// otherwise specified, it defaults to uint32
	SimpleType string
	Unsigned   bool
}

An Enum is a definition that will generate typed enumerable options.

func (Enum) Generate

func (en Enum) Generate(w *iohelp.ErrorWriter, settings GenerateSettings)

Generate writes a .go enum definition out to w.

type EnumOption

type EnumOption struct {
	Name    string
	Comment string
	// DeprecatedMessage is only provided if Deprecated is true.
	DeprecatedMessage string
	// Only one of Value or UintValue should e populated, dependant on
	// if the enum this option applies to is unsigned.
	Value      int64
	UintValue  uint64
	Deprecated bool
}

An EnumOption is one possible value for a field typed as a specific Enum.

type Field

type Field struct {
	FieldType
	Name    string
	Comment string
	// Tags are not written by default, and must be enabled via a compiler flag.
	Tags []Tag
	// DeprecatedMessage is only provided if Deprecated is true.
	DeprecatedMessage string
	Deprecated        bool
}

A Field is an individual, typed data component making up a Struct or Message.

type FieldType

type FieldType struct {
	Simple string
	Map    *MapType
	Array  *FieldType
}

A FieldType is a union of three choices: Simple types, array types, and map types. Only one of the three should be provided for a given FieldType.

type File

type File struct {
	// FileName is an optional argument defining where this
	// bebop file came from. This argument is only used to
	// determine where relative import files lie. If relative
	// imports are not used, this argument is not read. If
	// FileName is a relative path, it will be treated as
	// relative to os.Getwd().
	FileName string

	// GoPackage is the value of this file's go_package const,
	// should it be defined and string-typed.
	GoPackage string

	Structs  []Struct
	Messages []Message
	Enums    []Enum
	Unions   []Union
	Consts   []Const
	Imports  []string
}

A File is a structured representation of a .bop file.

func ReadFile

func ReadFile(r io.Reader) (File, []string, error)

ReadFile reads out a bebop file. If r is a FileNamer, like an *os.File, the output's FileName will be populated. In addition to fatal errors, string warnings may also be output.

func (File) Generate

func (f File) Generate(inputWriter io.Writer, settings GenerateSettings) error

Generate writes a .go file out to w. If f has imports, it will parse the files at those imports and generate them according to settings.

func (File) Validate

func (f File) Validate() error

Validate verifies a File can be successfully generated.

type FileNamer added in v0.2.0

type FileNamer interface {
	Name() string
}

type GenerateSettings

type GenerateSettings struct {
	// PackageName is optional if the target bebop file defines a go_package
	// constant. If both are provided, PackageName will take precedence.
	PackageName string

	ImportGenerationMode

	GenerateUnsafeMethods     bool
	SharedMemoryStrings       bool
	GenerateFieldTags         bool
	PrivateDefinitions        bool
	AlwaysUsePointerReceivers bool
	// contains filtered or unexported fields
}

GenerateSettings holds customization options for what Generate should do.

func (GenerateSettings) Validate added in v0.2.0

func (gs GenerateSettings) Validate() error

type ImportGenerationMode added in v0.2.0

type ImportGenerationMode uint8
const (
	// ImportGenerationModeSeparate will generate separate go files for
	// every bebop file, and will assume that imported files are
	// already generated. If imported file types are used and their containing
	// files do not contain a go_package constant, this mode will fail.
	ImportGenerationModeSeparate ImportGenerationMode = iota

	// ImportGenerationModeCombined will generate one go file including
	// all definitions from all imports. This does not require go_package
	// is defined anywhere, and maintains compatibility with files compilable
	// by the original bebopc compiler.
	ImportGenerationModeCombined ImportGenerationMode = iota
)

type MapType

type MapType struct {
	// Keys may only be named types
	Key   string
	Value FieldType
}

A MapType is a key-value type pair, where the key must be a primitive builtin type.

type Message

type Message struct {
	Name    string
	Comment string
	Fields  map[uint8]Field
	OpCode  uint32
	// Namespace is only provided for imported types, and only
	// used in code generation.
	Namespace string
}

A Message is a record type where all fields are optional and keyed to indices.

func (Message) Generate

func (msg Message) Generate(w io.Writer, settings GenerateSettings)

Generate writes a .go message definition out to w.

type Record

type Record interface {
	// MarshalBebop converts a bebop record to wire format. It is recommended over
	// EncodeBebop for performance.
	MarshalBebop() []byte
	// MarshalBebopTo writes a bebop record to an existing byte slice. It performs no
	// checks to ensure the given byte slice is large enough to contain the record.
	MarshalBebopTo([]byte) (n int)
	// UnmarshalBebop is parallel to Marshal as Decode is to Encode. It has similar
	// performance improvements.
	UnmarshalBebop([]byte) error
	// EncodeBebop writes a bebop record in wire format to a writer. It is slower (~6x)
	// than MarshalBebop, and is only recommended for uses where the record size is both
	// larger than a network packet and able to be acted upon as writer receives the byte
	// stream, not only after the entire message has been received.
	EncodeBebop(io.Writer) error
	// DecodeBebop is to EncodeBebop as UnmarshalBebop is to MarshalBebop
	DecodeBebop(io.Reader) error
	// Size reports how many bytes a record takes up. It is only valid for the state of the
	// record when Size is called.
	Size() int
}

A Record can be serialized to and from a bebop structure.

type Struct

type Struct struct {
	Name    string
	Comment string
	Fields  []Field
	// If OpCode is defined, wire encodings of the struct can be
	// preceded by the OpCode.
	OpCode uint32
	// Namespace is only provided for imported types, and only
	// used in code generation.
	Namespace string
	// If ReadOnly is true, generated code for the struct will
	// provide field getters instead of exporting fields.
	ReadOnly bool
}

A Struct is a record type where all fields are required.

func (Struct) Generate

func (st Struct) Generate(w io.Writer, settings GenerateSettings)

Generate writes a .go struct definition out to w.

type Tag added in v0.2.2

type Tag struct {
	Key   string
	Value string
	// Boolean is set if Value is empty, in the form `key`, not `key:""`.
	Boolean bool
}

A Tag is a Go struct field tag, e.g. `json:"userId,omitempty"`

type Union added in v0.0.9

type Union struct {
	Name    string
	Comment string
	Fields  map[uint8]UnionField
	OpCode  uint32
	// Namespace is only provided for imported types, and only
	// used in code generation.
	Namespace string
}

A Union is like a message where explicitly one field will be provided.

func (Union) Generate added in v0.0.9

func (u Union) Generate(w io.Writer, settings GenerateSettings)

Generate writes a .go union definition out to w.

type UnionField added in v0.0.9

type UnionField struct {
	Message *Message
	Struct  *Struct
	// Tags are not written by default, ard must be enabled via a compiler flag.
	Tags []Tag
	// DeprecatedMessage is only provided if Deprecated is true.
	DeprecatedMessage string
	Deprecated        bool
}

A UnionField is either a Message, Struct, or Union, defined inline.

Directories

Path Synopsis
internal
Package iohelp provides common io utilities for bebop generated code.
Package iohelp provides common io utilities for bebop generated code.
main

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL