Skip to content

Commit

Permalink
fix: resolve import collisions for enums (#341)
Browse files Browse the repository at this point in the history
Similar to #339. Also fixes generated functions
  • Loading branch information
doochik authored Aug 4, 2021
1 parent 63f9211 commit 50fe34e
Show file tree
Hide file tree
Showing 8 changed files with 210 additions and 15 deletions.
24 changes: 19 additions & 5 deletions integration/avoid-import-conflicts/simple-test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,21 @@
import { Simple } from './simple';
import { Simple, SimpleEnum as LocalSimpleEnum, SimpleEnums } from './simple';
import { SimpleEnum as ImportSimpleEnum } from './simple2';

describe('simple', () => {
it('generates types correctly', () => {
const simple = Simple.fromPartial({});
describe('Simple', () => {
it('type checking works correctly for interfaces', () => {
const simple: Simple = {
name: 'foo',
otherSimple: {
name: 'bar',
age: 1,
},
}
});
});

it('type checking works correctly for enums', () => {
const simpleEnum: SimpleEnums = {
localEnum: LocalSimpleEnum.LOCAL_BAR,
importEnum: ImportSimpleEnum.IMPORT_FOO,
}
});
})
Binary file modified integration/avoid-import-conflicts/simple.bin
Binary file not shown.
13 changes: 13 additions & 0 deletions integration/avoid-import-conflicts/simple.proto
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,20 @@ syntax = "proto3";
package simple;
import "simple2.proto";

enum SimpleEnum {
LOCAL_DEFAULT = 0;
LOCAL_FOO = 1;
LOCAL_BAR = 2;
}

message Simple {
string name = 1;
simple2.Simple otherSimple = 2;
}

message SimpleEnums {
SimpleEnum local_enum = 1;
simple2.SimpleEnum import_enum = 2;
}


134 changes: 127 additions & 7 deletions integration/avoid-import-conflicts/simple.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,61 @@
/* eslint-disable */
import { util, configure, Writer, Reader } from 'protobufjs/minimal';
import * as Long from 'long';
import { Simple as Simple1 } from './simple2';
import {
SimpleEnum as SimpleEnum1,
Simple as Simple2,
simpleEnumFromJSON as simpleEnumFromJSON3,
simpleEnumToJSON as simpleEnumToJSON4,
} from './simple2';

export const protobufPackage = 'simple';

export enum SimpleEnum {
LOCAL_DEFAULT = 0,
LOCAL_FOO = 1,
LOCAL_BAR = 2,
UNRECOGNIZED = -1,
}

export function simpleEnumFromJSON(object: any): SimpleEnum {
switch (object) {
case 0:
case 'LOCAL_DEFAULT':
return SimpleEnum.LOCAL_DEFAULT;
case 1:
case 'LOCAL_FOO':
return SimpleEnum.LOCAL_FOO;
case 2:
case 'LOCAL_BAR':
return SimpleEnum.LOCAL_BAR;
case -1:
case 'UNRECOGNIZED':
default:
return SimpleEnum.UNRECOGNIZED;
}
}

export function simpleEnumToJSON(object: SimpleEnum): string {
switch (object) {
case SimpleEnum.LOCAL_DEFAULT:
return 'LOCAL_DEFAULT';
case SimpleEnum.LOCAL_FOO:
return 'LOCAL_FOO';
case SimpleEnum.LOCAL_BAR:
return 'LOCAL_BAR';
default:
return 'UNKNOWN';
}
}

export interface Simple {
name: string;
otherSimple: Simple1 | undefined;
otherSimple: Simple2 | undefined;
}

export interface SimpleEnums {
localEnum: SimpleEnum;
importEnum: SimpleEnum1;
}

const baseSimple: object = { name: '' };
Expand All @@ -18,7 +66,7 @@ export const Simple = {
writer.uint32(10).string(message.name);
}
if (message.otherSimple !== undefined) {
Simple1.encode(message.otherSimple, writer.uint32(18).fork()).ldelim();
Simple2.encode(message.otherSimple, writer.uint32(18).fork()).ldelim();
}
return writer;
},
Expand All @@ -34,7 +82,7 @@ export const Simple = {
message.name = reader.string();
break;
case 2:
message.otherSimple = Simple1.decode(reader, reader.uint32());
message.otherSimple = Simple2.decode(reader, reader.uint32());
break;
default:
reader.skipType(tag & 7);
Expand All @@ -52,7 +100,7 @@ export const Simple = {
message.name = '';
}
if (object.otherSimple !== undefined && object.otherSimple !== null) {
message.otherSimple = Simple1.fromJSON(object.otherSimple);
message.otherSimple = Simple2.fromJSON(object.otherSimple);
} else {
message.otherSimple = undefined;
}
Expand All @@ -63,7 +111,7 @@ export const Simple = {
const obj: any = {};
message.name !== undefined && (obj.name = message.name);
message.otherSimple !== undefined &&
(obj.otherSimple = message.otherSimple ? Simple1.toJSON(message.otherSimple) : undefined);
(obj.otherSimple = message.otherSimple ? Simple2.toJSON(message.otherSimple) : undefined);
return obj;
},

Expand All @@ -75,14 +123,86 @@ export const Simple = {
message.name = '';
}
if (object.otherSimple !== undefined && object.otherSimple !== null) {
message.otherSimple = Simple1.fromPartial(object.otherSimple);
message.otherSimple = Simple2.fromPartial(object.otherSimple);
} else {
message.otherSimple = undefined;
}
return message;
},
};

const baseSimpleEnums: object = { localEnum: 0, importEnum: 0 };

export const SimpleEnums = {
encode(message: SimpleEnums, writer: Writer = Writer.create()): Writer {
if (message.localEnum !== 0) {
writer.uint32(8).int32(message.localEnum);
}
if (message.importEnum !== 0) {
writer.uint32(16).int32(message.importEnum);
}
return writer;
},

decode(input: Reader | Uint8Array, length?: number): SimpleEnums {
const reader = input instanceof Reader ? input : new Reader(input);
let end = length === undefined ? reader.len : reader.pos + length;
const message = { ...baseSimpleEnums } as SimpleEnums;
while (reader.pos < end) {
const tag = reader.uint32();
switch (tag >>> 3) {
case 1:
message.localEnum = reader.int32() as any;
break;
case 2:
message.importEnum = reader.int32() as any;
break;
default:
reader.skipType(tag & 7);
break;
}
}
return message;
},

fromJSON(object: any): SimpleEnums {
const message = { ...baseSimpleEnums } as SimpleEnums;
if (object.localEnum !== undefined && object.localEnum !== null) {
message.localEnum = simpleEnumFromJSON(object.localEnum);
} else {
message.localEnum = 0;
}
if (object.importEnum !== undefined && object.importEnum !== null) {
message.importEnum = simpleEnumFromJSON3(object.importEnum);
} else {
message.importEnum = 0;
}
return message;
},

toJSON(message: SimpleEnums): unknown {
const obj: any = {};
message.localEnum !== undefined && (obj.localEnum = simpleEnumToJSON(message.localEnum));
message.importEnum !== undefined && (obj.importEnum = simpleEnumToJSON4(message.importEnum));
return obj;
},

fromPartial(object: DeepPartial<SimpleEnums>): SimpleEnums {
const message = { ...baseSimpleEnums } as SimpleEnums;
if (object.localEnum !== undefined && object.localEnum !== null) {
message.localEnum = object.localEnum;
} else {
message.localEnum = 0;
}
if (object.importEnum !== undefined && object.importEnum !== null) {
message.importEnum = object.importEnum;
} else {
message.importEnum = 0;
}
return message;
},
};

type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined;
export type DeepPartial<T> = T extends Builtin
? T
Expand Down
Binary file modified integration/avoid-import-conflicts/simple2.bin
Binary file not shown.
6 changes: 6 additions & 0 deletions integration/avoid-import-conflicts/simple2.proto
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
syntax = "proto3";
package simple2;

enum SimpleEnum {
IMPORT_DEFAULT = 0;
IMPORT_FOO = 10;
IMPORT_BAR = 11;
}

message Simple {
string name = 1;
int32 age = 2;
Expand Down
38 changes: 38 additions & 0 deletions integration/avoid-import-conflicts/simple2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,44 @@ import * as Long from 'long';

export const protobufPackage = 'simple2';

export enum SimpleEnum {
IMPORT_DEFAULT = 0,
IMPORT_FOO = 10,
IMPORT_BAR = 11,
UNRECOGNIZED = -1,
}

export function simpleEnumFromJSON(object: any): SimpleEnum {
switch (object) {
case 0:
case 'IMPORT_DEFAULT':
return SimpleEnum.IMPORT_DEFAULT;
case 10:
case 'IMPORT_FOO':
return SimpleEnum.IMPORT_FOO;
case 11:
case 'IMPORT_BAR':
return SimpleEnum.IMPORT_BAR;
case -1:
case 'UNRECOGNIZED':
default:
return SimpleEnum.UNRECOGNIZED;
}
}

export function simpleEnumToJSON(object: SimpleEnum): string {
switch (object) {
case SimpleEnum.IMPORT_DEFAULT:
return 'IMPORT_DEFAULT';
case SimpleEnum.IMPORT_FOO:
return 'IMPORT_FOO';
case SimpleEnum.IMPORT_BAR:
return 'IMPORT_BAR';
default:
return 'UNKNOWN';
}
}

export interface Simple {
name: string;
age: number;
Expand Down
10 changes: 7 additions & 3 deletions src/enums.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ export function generateEnumFromJson(ctx: Context, fullName: string, enumDesc: E
const { options, utils } = ctx;
const chunks: Code[] = [];

chunks.push(code`export function ${camelCase(fullName)}FromJSON(object: any): ${fullName} {`);
const functionName = camelCase(fullName) + 'FromJSON';
chunks.push(code`export function ${def(functionName)}(object: any): ${fullName} {`);
chunks.push(code`switch (object) {`);

for (const valueDesc of enumDesc.value) {
Expand Down Expand Up @@ -92,7 +93,8 @@ export function generateEnumFromJson(ctx: Context, fullName: string, enumDesc: E
export function generateEnumToJson(fullName: string, enumDesc: EnumDescriptorProto): Code {
const chunks: Code[] = [];

chunks.push(code`export function ${camelCase(fullName)}ToJSON(object: ${fullName}): string {`);
const functionName = camelCase(fullName) + 'ToJSON';
chunks.push(code`export function ${def(functionName)}(object: ${fullName}): string {`);
chunks.push(code`switch (object) {`);

for (const valueDesc of enumDesc.value) {
Expand All @@ -108,7 +110,9 @@ export function generateEnumToJson(fullName: string, enumDesc: EnumDescriptorPro
/** Generates a function with a big switch statement to encode our string enum -> int value. */
export function generateEnumToNumber(fullName: string, enumDesc: EnumDescriptorProto): Code {
const chunks: Code[] = [];
chunks.push(code`export function ${camelCase(fullName)}ToNumber(object: ${fullName}): number {`);

const functionName = camelCase(fullName) + 'ToNumber';
chunks.push(code`export function ${def(functionName)}(object: ${fullName}): number {`);
chunks.push(code`switch (object) {`);
for (const valueDesc of enumDesc.value) {
chunks.push(code`case ${fullName}.${valueDesc.name}: return ${valueDesc.number};`);
Expand Down

0 comments on commit 50fe34e

Please sign in to comment.