in packages/jsii-pacmak/lib/targets/go/runtime/runtime-type-checking.ts [457:560]
public emit(code: CodeMaker, scope: Package): void {
const validTypes = new Array<string>();
code.line(`switch ${expression}.(type) {`);
for (const type of types) {
const typeName = type.scopedReference(scope);
validTypes.push(typeName);
// Maps a type to the conversion instructions to the ${typeName} type
const acceptableTypes = new Map<
string,
| ((code: CodeMaker, inVar: string, outVar: string) => void)
| undefined
>();
acceptableTypes.set(typeName, undefined);
switch (typeName) {
case '*float64':
// For numbers, we accept everything that implictly converts to float64 (pointer & not)
acceptableTypes.set('float64', (code, inVar, outVar) =>
code.line(`${outVar} := &${inVar}`),
);
const ALTERNATE_TYPES = [
'int',
'uint',
'int8',
'int16',
'int32',
'int64',
'uint8',
'uint16',
'uint32',
'uint64',
];
for (const otherType of ALTERNATE_TYPES) {
const varName = createHash('sha256')
.update(expression)
.digest('hex')
.slice(6);
acceptableTypes.set(`*${otherType}`, (code) => {
code.openBlock(
`${varName} := func (v *${otherType}) *float64`,
);
code.openBlock('if v == nil {');
code.line('return nil');
code.closeBlock();
code.line(`val := float64(*v)`);
code.line(`return &val`);
code.closeBlock('()');
});
acceptableTypes.set(otherType, (code) => {
code.openBlock(
`${varName} := func (v ${otherType}) *float64`,
);
code.line(`val := float64(v)`);
code.line(`return &val`);
code.closeBlock('()');
});
}
break;
default:
// Accept pointer and non-pointer versions of everything
if (typeName.startsWith('*')) {
const nonPointerType = typeName.slice(1);
acceptableTypes.set(nonPointerType, (code, inVar, outVar) =>
code.line(`${outVar} := &${inVar}`),
);
}
}
for (const [acceptableType, conversion] of acceptableTypes) {
code.indent(`case ${acceptableType}:`);
const outVar = /^[a-z0-9_]+$/.test(expression) ? expression : `v`;
const validation = Validation.forTypeMap(
outVar,
description,
type.typeMap,
);
if (validation) {
const inVar = conversion ? `${outVar}_` : outVar;
code.line(`${inVar} := ${expression}.(${acceptableType})`);
if (conversion) {
conversion(code, inVar, outVar);
}
validation.emit(code, scope);
} else {
code.line('// ok');
}
code.unindent(false);
}
}
code.indent('default:');
if (hasInterface)
code.openBlock(
`if !${JSII_RT_ALIAS}.IsAnonymousProxy(${expression})`,
);
code.line(
returnErrorf(
`${description} must be one of the allowed types: ${validTypes.join(
', ',
)}; received @{${expression}:#v} (a @{${expression}:T})`,
),
);
if (hasInterface) code.closeBlock();
code.unindent('}');
}
}