Skip to content

Commit

Permalink
First iteration of schema gen on entities
Browse files Browse the repository at this point in the history
  • Loading branch information
alxmrs committed Mar 4, 2020
1 parent 78bf4f0 commit 2ce6da2
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 9 deletions.
12 changes: 9 additions & 3 deletions src/tools/schema2base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {SchemaGraph, SchemaNode} from './schema2graph.js';
import {ParticleSpec} from '../runtime/particle-spec.js';

export interface ClassGenerator {
addField(field: string, typeChar: string, isOptional: boolean, refClassName: string|null): void;
addField(field: string, typeChar: string, isOptional: boolean, refClassName: string|null, isCollection: boolean): void;
generate(schemaHash: string, fieldCount: number): string;
}

Expand Down Expand Up @@ -78,14 +78,20 @@ export abstract class Schema2Base {
for (const [field, descriptor] of fields) {
if (descriptor.kind === 'schema-primitive') {
if (['Text', 'URL', 'Number', 'Boolean'].includes(descriptor.type)) {
generator.addField(field, descriptor.type[0], false, null);
generator.addField(field, descriptor.type[0], false, null, false);
} else {
throw new Error(`Schema type '${descriptor.type}' for field '${field}' is not supported`);
}
} else if (descriptor.kind === 'schema-reference') {
generator.addField(field, 'R', false, node.refs.get(field).name);
generator.addField(field, 'R', false, node.refs.get(field).name, false);
} else if (descriptor.kind === 'schema-collection' && descriptor.schema.kind === 'schema-reference') {
// TODO: support collections of references
} else if (descriptor.kind === 'schema-collection') {
const schema = descriptor.schema;
if (!['Text', 'URL', 'Number', 'Boolean'].includes(schema.type)) {
throw new Error(`Schema type '${schema.type}' for field '${field}' is not supported`);
}
generator.addField(field, schema.type[0], false, null, true);
} else {
throw new Error(`Schema kind '${descriptor.kind}' for field '${field}' is not supported`);
}
Expand Down
2 changes: 1 addition & 1 deletion src/tools/schema2cpp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ class CppGenerator implements ClassGenerator {

constructor(readonly node: SchemaNode, readonly namespace: string) {}

addField(field: string, typeChar: string, isOptional: boolean, refClassName: string|null) {
addField(field: string, typeChar: string, isOptional: boolean, refClassName: string|null, isCollection: boolean = false) {
const fixed = fixName(field);
const valid = `${field}_valid_`;
let {type, defaultVal, isString} = typeMap[typeChar];
Expand Down
36 changes: 31 additions & 5 deletions src/tools/schema2kotlin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ const keywords = [
];

const typeMap = {
'T': {type: 'String', decodeFn: 'decodeText()', defaultVal: `""`},
'U': {type: 'String', decodeFn: 'decodeText()', defaultVal: `""`},
'N': {type: 'Double', decodeFn: 'decodeNum()', defaultVal: '0.0'},
'B': {type: 'Boolean', decodeFn: 'decodeBool()', defaultVal: 'false'},
'T': {type: 'String', decodeFn: 'decodeText()', defaultVal: `""`, schemaType: 'FieldType.Text'},
'U': {type: 'String', decodeFn: 'decodeText()', defaultVal: `""`, schemaType: 'FieldType.Text'},
'N': {type: 'Double', decodeFn: 'decodeNum()', defaultVal: '0.0', schemaType: 'FieldType.Number'},
'B': {type: 'Boolean', decodeFn: 'decodeBool()', defaultVal: 'false', schemaType: 'FieldType.Boolean'},
};

export class Schema2Kotlin extends Schema2Base {
Expand All @@ -54,6 +54,7 @@ package ${this.scope}
// Current implementation doesn't support references or optional field detection
import arcs.sdk.*
import arcs.core.data.*
${this.opts.wasm ? 'import arcs.sdk.wasm.*' : 'import arcs.core.storage.api.toPrimitiveValue\nimport arcs.core.data.RawEntity\nimport arcs.core.data.util.toReferencable\nimport arcs.core.data.util.ReferencablePrimitive'}
`;
}
Expand Down Expand Up @@ -144,11 +145,13 @@ class KotlinGenerator implements ClassGenerator {
fieldSerializes: string[] = [];
fieldDeserializes: string[] = [];
fieldsForToString: string[] = [];
singletonSchemaFields: string[] = [];
collectionSchemaFields: string[] = [];

constructor(readonly node: SchemaNode, private readonly opts: minimist.ParsedArgs) {}

// TODO: allow optional fields in kotlin
addField(field: string, typeChar: string, isOptional: boolean, refClassName: string|null) {
addField(field: string, typeChar: string, isOptional: boolean, refClassName: string|null, isCollection: boolean = false) {
// TODO: support reference types in kotlin
if (typeChar === 'R') return;

Expand Down Expand Up @@ -181,6 +184,12 @@ class KotlinGenerator implements ClassGenerator {
this.fieldSerializes.push(`"${field}" to ${fixed}.toReferencable()`);
this.fieldDeserializes.push(`${fixed} = data.singletons["${fixed}"].toPrimitiveValue(${type}::class, ${defaultVal})`);
this.fieldsForToString.push(`${fixed} = $${fixed}`);
if (isCollection) {
this.collectionSchemaFields.push(`"${field}" to ${typeMap[typeChar].schemaType}`);
} else {
this.singletonSchemaFields.push(`"${field}" to ${typeMap[typeChar].schemaType}`);
}

}

generate(schemaHash: string, fieldCount: number): string {
Expand All @@ -196,6 +205,8 @@ class KotlinGenerator implements ClassGenerator {
const withFields = (populate: string) => fieldCount === 0 ? '' : populate;
const withoutFields = (populate: string) => fieldCount === 0 ? populate : '';

const schemaNames = this.node.schema.names.map(n => `SchemaName("${n}")`);

return `\
class ${name}() : ${this.getType('Entity')} {
Expand Down Expand Up @@ -257,6 +268,21 @@ ${this.opts.wasm ? `
class ${name}_Spec() : ${this.getType('EntitySpec')}<${name}> {
companion object {
val schema = Schema(
listOf(${schemaNames.join('\n ')}),
SchemaFields(
singletons = mapOf(
${this.singletonSchemaFields.join(',\n ')}
),
collections = mapOf(
${this.collectionSchemaFields.join(',\n ')}
)
),
"${schemaHash}"
)
}
override fun create() = ${name}()
${!this.opts.wasm ? `
override fun deserialize(data: RawEntity): ${name} {
Expand Down

0 comments on commit 2ce6da2

Please sign in to comment.