| // 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 |
| } |