| // 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. |
| |
| /** |
| * @fileoverview Utilities for manipulating types. |
| * @private |
| */ |
| |
| var Type = require('./type.js'); |
| var kind = require('./kind.js'); |
| |
| // TODO(bprosnitz) Should we add other helpers? Or is it better just to directly |
| // create the types in js? |
| |
| /** |
| * @summary Namespace of pre-defined VDL Types. |
| * @description Namespace of pre-defined VDL Types. |
| * @namespace |
| * @memberof module:vanadium.vdl |
| */ |
| var types = { |
| /** |
| * @type {module:vanadium.vdl.Type} |
| * @const |
| */ |
| ANY: primitiveType(kind.ANY), |
| /** |
| * @type {module:vanadium.vdl.Type} |
| * @const |
| */ |
| BOOL: primitiveType(kind.BOOL), |
| /** |
| * @type {module:vanadium.vdl.Type} |
| * @const |
| */ |
| BYTE: primitiveType(kind.BYTE), |
| /** |
| * @type {module:vanadium.vdl.Type} |
| * @const |
| */ |
| UINT16: primitiveType(kind.UINT16), |
| /** |
| * @type {module:vanadium.vdl.Type} |
| * @const |
| */ |
| UINT32: primitiveType(kind.UINT32), |
| /** |
| * @type {module:vanadium.vdl.Type} |
| * @const |
| */ |
| UINT64: primitiveType(kind.UINT64), |
| /** |
| * @type {module:vanadium.vdl.Type} |
| * @const |
| */ |
| INT16: primitiveType(kind.INT16), |
| /** |
| * @type {module:vanadium.vdl.Type} |
| * @const |
| */ |
| INT32: primitiveType(kind.INT32), |
| /** |
| * @type {module:vanadium.vdl.Type} |
| * @const |
| */ |
| INT64: primitiveType(kind.INT64), |
| /** |
| * @type {module:vanadium.vdl.Type} |
| * @const |
| */ |
| FLOAT32: primitiveType(kind.FLOAT32), |
| /** |
| * @type {module:vanadium.vdl.Type} |
| * @const |
| */ |
| FLOAT64: primitiveType(kind.FLOAT64), |
| /** |
| * @type {module:vanadium.vdl.Type} |
| * @const |
| */ |
| COMPLEX64: primitiveType(kind.COMPLEX64), |
| /** |
| * @type {module:vanadium.vdl.Type} |
| * @const |
| */ |
| COMPLEX128: primitiveType(kind.COMPLEX128), |
| /** |
| * @type {module:vanadium.vdl.Type} |
| * @const |
| */ |
| STRING: primitiveType(kind.STRING), |
| /** |
| * @type {module:vanadium.vdl.Type} |
| * @const |
| */ |
| TYPEOBJECT: Type.prototype._type // So that === works for types.TypeObject |
| }; |
| /** |
| * @type {module:vanadium.vdl.Type} |
| * @const |
| */ |
| types.ERROR = defineOptionalErrorType(); |
| |
| /** |
| * @type {module:vanadium.vdl.Type} |
| * @const |
| */ |
| types.JSVALUE = defineJSValueType(); |
| |
| module.exports = types; |
| |
| function defineOptionalErrorType() { |
| var nilErrorType = new Type(); |
| |
| // TODO(bprosnitz) Should we add an error constructor so error objects have |
| // the same prototype? (this will be the case once this is generated by VDL as |
| // well) |
| var retryCodeType = new Type(); |
| retryCodeType.name = ''; |
| retryCodeType.kind = kind.ENUM; |
| retryCodeType.labels = [ |
| 'NoRetry', |
| 'RetryConnection', |
| 'RetryRefetch', |
| 'RetryBackoff' |
| ]; |
| var paramListType = new Type(); |
| paramListType.name = ''; |
| paramListType.kind = kind.LIST; |
| paramListType.elem = types.ANY; |
| |
| var errorType = new Type(); |
| errorType.name = 'error'; |
| errorType.kind = kind.STRUCT; |
| errorType.fields = [ |
| { |
| name: 'Id', |
| type: types.STRING |
| }, |
| { |
| name: 'RetryCode', |
| type: retryCodeType |
| }, |
| { |
| name: 'Msg', |
| type: types.STRING |
| }, |
| { |
| name: 'ParamList', |
| type: paramListType |
| } |
| ]; |
| nilErrorType.name = ''; |
| nilErrorType.kind = kind.OPTIONAL; |
| nilErrorType.elem = errorType; |
| |
| return nilErrorType; |
| } |
| |
| // The JSValueType is a special type for JavaScript. Services will default to |
| // sending and receiving this type when they do not specify a type in their |
| // service signature. |
| // TODO(alexfandrianto): We are still use types.ANY instead of types.JSVALUE. |
| // TODO(alexfandrianto): We should consider moving this type into VDL. |
| // See the issue: https://github.com/veyron/release-issues/issues/760 |
| // Warning: In the rare case that someone defines their own JSValue, they will |
| // not have the expected behavior in encode/decode/canonicalize because JSValue |
| // is heavily special-cased. |
| function defineJSValueType() { |
| var JSValueType = new Type(); |
| var EmptyStruct = new Type(); |
| var ByteList = new Type(); |
| var JSValueList = new Type(); |
| var JSKeyValueList = new Type(); |
| var JSKeyValuePair = new Type(); |
| var JSStringValueList = new Type(); |
| var JSStringValuePair = new Type(); |
| |
| // Fill JSValue |
| JSValueType.name = 'JSValue'; |
| JSValueType.kind = kind.UNION; |
| JSValueType.fields = [ |
| { |
| name: 'Null', |
| type: EmptyStruct |
| }, |
| { |
| name: 'Boolean', |
| type: types.BOOL |
| }, |
| { |
| name: 'Number', |
| type: types.FLOAT64 |
| }, |
| { |
| name: 'String', |
| type: types.STRING |
| }, |
| { |
| name: 'Bytes', |
| type: ByteList |
| }, |
| { |
| name: 'List', |
| type: JSValueList |
| }, |
| { |
| name: 'Set', |
| type: JSValueList |
| }, |
| { |
| name: 'Map', |
| type: JSKeyValueList |
| }, |
| { |
| name: 'Object', |
| type: JSStringValueList |
| } |
| ]; |
| |
| // Define the rest of EmptyStruct |
| // Add a name, since VDL does not allow unnamed, empty structs. |
| EmptyStruct.kind = kind.STRUCT; |
| EmptyStruct.fields = []; |
| EmptyStruct.name = 'EmptyStruct'; |
| |
| // Define the rest of ByteList |
| ByteList.kind = kind.LIST; |
| ByteList.elem = types.BYTE; |
| |
| // Define the rest of JSValueList |
| JSValueList.kind = kind.LIST; |
| JSValueList.elem = types.ANY; |
| |
| // Define the rest of JSKeyValueList |
| JSKeyValueList.kind = kind.LIST; |
| JSKeyValueList.elem = JSKeyValuePair; |
| |
| // Define the rest of JSKeyValuePair |
| JSKeyValuePair.kind = kind.STRUCT; |
| JSKeyValuePair.fields = [ |
| { |
| name: 'Key', |
| type: types.ANY |
| }, |
| { |
| name: 'Value', |
| type: types.ANY |
| } |
| ]; |
| |
| // Define the rest of JSStringValueList |
| JSStringValueList.kind = kind.LIST; |
| JSStringValueList.elem = JSStringValuePair; |
| |
| // Define the rest of JSStringValuePair |
| JSStringValuePair.kind = kind.STRUCT; |
| JSStringValuePair.fields = [ |
| { |
| name: 'Key', |
| type: types.STRING |
| }, |
| { |
| name: 'Value', |
| type: types.ANY |
| } |
| ]; |
| |
| return JSValueType; |
| } |
| |
| // Primitive types only need a kind. They have an empty name by default. |
| function primitiveType(kind) { |
| var prim = new Type(); |
| prim.kind = kind; |
| return prim; |
| } |