blob: 7aedf8072eee3cdbc938217b3a6a3c85530d80bc [file] [log] [blame] [edit]
// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package vdltool defines types used by the vdl tool itself, including the
// format of vdl.config files.
package vdltool
// Config specifies the configuration for the vdl tool. This is typically
// represented in optional "vdl.config" files in each vdl source package. Each
// vdl.config file implicitly imports this package. E.g. you may refer to
// vdltool.Config in the "vdl.config" file without explicitly importing vdltool.
type Config struct {
// GenLanguages restricts the set of code generation languages. If the set is
// empty, all supported languages are allowed to be generated.
GenLanguages set[GenLanguage]
// Language-specific configurations.
Go GoConfig
Java JavaConfig
Javascript JavascriptConfig
Swift SwiftConfig
}
// GenLanguage enumerates the known code generation languages.
type GenLanguage enum {
Go
Java
Javascript
Swift
}
// GoConfig specifies go specific configuration.
type GoConfig struct {
// WireToNativeTypes specifies the mapping from a VDL wire type to its Go
// native type representation. This is rarely used and easy to configure
// incorrectly; usage is currently restricted to packages that are explicitly
// whitelisted.
//
// WireToNativeTypes are meant for scenarios where there is an idiomatic Go
// type used in your code, but you need a standard VDL representation for wire
// compatibility. E.g. the VDL time package defines Duration and Time for
// wire compatibility, but we want the generated code to use the standard Go
// time package.
//
// The key of the map is the name of the VDL type (aka WireType), which must
// be defined in the vdl package associated with the vdl.config file.
//
// The code generator assumes the existence of a pair of conversion functions
// converting between the wire and native types, and will automatically call
// vdl.RegisterNative with these function names.
//
// Assuming the name of the WireType is Foo:
// func fooToNative(x Foo, n *Native) error
// func fooFromNative(x *Foo, n Native) error
WireToNativeTypes map[string]GoType
}
// GoType describes the Go type information associated with a VDL type.
// See v.io/x/ref/lib/vdl/testdata/native for examples.
type GoType struct {
// Kind is the kind of Type.
Kind GoKind
// Type is the Go type to use in generated code, instead of the VDL type.
Type string
// Zero specifies zero value setting and checking behavior.
Zero GoZero
// ToNative and FromNative overrides the names of the native conversion
// functions. If unspecified, the default functions are of the form:
// WireTypeToNative(wire WireType, native *NativeType) error
// WireTypeFromNative(wire *WireType, native NativeType) error
ToNative string
FromNative string
// Imports are the Go imports referenced by the Type, ToNative and FromNative
// fields. In each field, use the standard local package name, and specify
// the import package here. E.g. to specify the native type time.Time:
// GoType{
// Kind: Struct,
// Type: "time.Time",
// Zero: {Mode: Canonical, IsZero: ".IsZero()"},
// Imports: {{Path: "time", Name: "time"}},
// }
Imports []GoImport
}
// GoKind describes the kind of Go type.
type GoKind enum {
Struct
Bool
Number
String
Array
Slice
Map
Pointer
Iface
}
// GoImport describes Go import information.
type GoImport struct {
// Path is the package path that uniquely identifies the imported package.
Path string
// Name is the name of the package identified by Path. Due to Go conventions,
// it is typically just the basename of Path, but may be set to something
// different if the imported package doesn't follow Go conventions.
Name string
}
// GoZero describes Go zero value behavior.
//
// REQUIRED: Either Mode == Unique or IsZero is set. We will not perform
// native/wire conversions to check zero values.
type GoZero struct {
Mode GoZeroMode
// IsZero specifies a field, method or function that returns true iff the
// native value represents the VDL zero value.
//
// If IsZero starts with a dot (.), it is assumed to be a field or method.
// The field type or method return type must be bool. Generated code will
// apply the IsZero string verbatim to expressions of the native type.
//
// If IsZero doesn't start with a dot(.), it is assumed to be a function whose
// return type must be bool. Generated code will call the function with a
// single argument that is an expression of the native type.
//
// TODO(toddw): The function form of IsZero isn't implemented.
IsZero string
// TODO(toddw): Add a SetZero field, which is like IsZero, but returns an
// expression that sets the zero value.
}
// GoZeroMode describes the relationship between the Go zero value of the native
// type, and the VDL zero value.
type GoZeroMode enum {
// Unknown specifies that the Go zero value does not represent the VDL zero
// value. This is the default.
//
// In this mode we generate slow code to perform native/wire conversions for
// setting zero values. To check zero values we require that the IsZero
// field, method or function is set.
Unknown
// Canonical specifies that the Go zero value of the native type is the
// canonical representation of the VDL zero value, but is not the only zero
// value representation. E.g. the zero value of native time.Time is the
// canonical representation of zero, but isn't the only zero since zeros also
// exist for different locations.
//
// In this mode we generate fast code for setting zero values. To check zero
// values we require that the IsZero field, method or function is set.
Canonical
// Unique specifies that the Go zero value of the native type is the only
// representation of the VDL zero value. E.g. the zero value of time.Duration
// (which has base type int64) is the only representation of zero.
//
// In this mode we generate fast code for both setting and checking zero
// values.
Unique
}
// JavaConfig specifies java specific configuration.
type JavaConfig struct {
// WireToNativeTypes specifies the mapping from a VDL wire type to its Java
// native type representation. This is rarely used and easy to configure
// incorrectly; usage is currently restricted to packages that are explicitly
// whitelisted.
//
// WireToNativeTypes are meant for scenarios where there is an idiomatic Java
// type used in your code, but you need a standard VDL representation for wire
// compatibility. E.g. the VDL time package defines Duration and Time for
// wire compatibility, but we want the generated code to use the org.joda.time
// package.
//
// The key of the map is the name of the VDL type (aka WireType), which must
// be defined in the vdl package associated with the vdl.config file.
//
// The code generator assumes that the conversion functions will be registered
// in java vdl package.
WireToNativeTypes map[string]string
// WireTypeRenames specifies the mapping from a VDL wire type name to its
// Java native type name.
//
// WireTypeRenames are meant for scenarios where the VDL wire name
// conflicts in some way with the Java native names, e.g., a VDL Integer
// type could be named VInteger for clarity.
//
// When combined with WireToNativeTypes, this feature allows us to attach
// functions to VDL types. For example, we may rename AccessList VDL type
// into WireAccessList and then map WireAccessList to our Java native type
// AccessList which defines functions on the VDL data.
//
// The key of the map is the name of the VDL wire type, which must be
// defined in the vdl package associated with the vdl.config file.
WireTypeRenames map[string]string
}
// JavascriptConfig specifies javascript specific configuration.
type JavascriptConfig struct {
}
// SwiftConfig specifies swift specific configuration for this package.
// Note that despite the SwiftConfig options for a given package (which should be
// very rare in practice), we still need to know the name of the swift module
// that this package relates to to properly understand import boundaries between
// projects/frameworks/modules.
//
// We do this by defining a file called "swiftmodule" that contains JUST the
// name of the Swift module at the root of your VDL packages. For example,
// if you have the VDL files for your Xcode project/target called UberForCats
// at /Users/aaron/uberforcats/vdl, then create
// /Users/aaron/uberforcats/vdl/com.uberforcats/swiftmodule and have it just contain
// "UberForCats". We then will treat any VDL files contained in that directory and
// any subdirectories as part of the UberForCats Swift module, ultimately letting
// the compiler and will automatically do the right thing if others import your package.
// If you don't do this then nobody will be able to import your VDL types in Swift,
// and you might end up with extra long class/pkg names (ComuberforcatsServicesProfit
// instead of ServicesProfit for $VDLROOT/com.uberforcats/services/profit).
//
// If you are creating multiple Swift modules for a given $VDLROOT then just place
// swiftmodule files at the logical boundaries. For eample, we do this for v.io/v23
// to be exported to the VanadiumCore framework, but everything under v.io/v23/services
// lives in the VanadiumServices framework.
type SwiftConfig struct {
// WireToNativeTypes specifies the mapping from a VDL wire type to its Swift
// native type representation. This is rarely used and easy to configure
// incorrectly; usage is currently restricted to packages that are explicitly
// whitelisted.
//
// WireToNativeTypes are meant for scenarios where there is an idiomatic Swift
// type used in your code, but you need a standard VDL representation for wire
// compatibility. E.g. the VDL time package defines Duration and Time for
// wire compatibility, but we want the generated code to use NSDate or NSTimeInterval
//
// The key of the map is the name of the VDL type (aka WireType), which must
// be defined in the vdl package associated with the vdl.config file.
//
// The code generator assumes that the conversion functions will be registered
// in Swift vdl package.
WireToNativeTypes map[string]string
}