Skip to content

Commit

Permalink
Simplify makeProtoRuntime
Browse files Browse the repository at this point in the history
  • Loading branch information
timostamm committed Feb 5, 2024
1 parent 8d4f81b commit 235b82c
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 89 deletions.
2 changes: 1 addition & 1 deletion packages/protobuf-bench/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ server would usually do.

| code generator | bundle size | minified | compressed |
|---------------------|------------------------:|-----------------------:|-------------------:|
| protobuf-es | 96,909 b | 41,490 b | 10,738 b |
| protobuf-es | 96,959 b | 41,479 b | 10,750 b |
| protobuf-javascript | 394,384 b | 288,654 b | 45,122 b |
18 changes: 12 additions & 6 deletions packages/protobuf/src/private/proto-runtime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ import { makeMessageType } from "./message-type.js";
import type { Extension } from "../extension.js";
import type { ExtensionFieldSource } from "./extensions.js";
import { makeExtension } from "./extensions.js";
import { makeJsonFormat } from "./json-format.js";
import { makeBinaryFormat } from "./binary-format.js";
import { makeUtilCommon } from "./util-common.js";

/**
* A facade that provides serialization and other internal functionality.
Expand Down Expand Up @@ -100,15 +103,18 @@ export interface ProtoRuntime {

export function makeProtoRuntime(
syntax: string,
json: JsonFormat,
bin: BinaryFormat,
util: Util,
newFieldList: Util["newFieldList"],
initFields: Util["initFields"],
): ProtoRuntime {
return {
syntax,
json,
bin,
util,
json: makeJsonFormat(),
bin: makeBinaryFormat(),
util: {
...makeUtilCommon(),
newFieldList,
initFields,
},
makeMessageType(
typeName: string,
fields: FieldListSource,
Expand Down
72 changes: 32 additions & 40 deletions packages/protobuf/src/proto2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,57 +13,49 @@
// limitations under the License.

import { makeProtoRuntime } from "./private/proto-runtime.js";
import { makeUtilCommon } from "./private/util-common.js";
import type { FieldListSource } from "./private/field-list.js";
import { InternalFieldList } from "./private/field-list.js";
import type { FieldList } from "./field-list.js";
import type { AnyMessage, Message } from "./message.js";
import { normalizeFieldInfos } from "./private/field-normalize.js";
import { makeBinaryFormat } from "./private/binary-format.js";
import { makeJsonFormat } from "./private/json-format.js";

/**
* Provides functionality for messages defined with the proto2 syntax.
*/
export const proto2 = makeProtoRuntime(
"proto2",
makeJsonFormat(),
makeBinaryFormat(),
{
...makeUtilCommon(),
newFieldList(fields: FieldListSource): FieldList {
return new InternalFieldList(fields, (source) =>
normalizeFieldInfos(source, false),
);
},
// TODO merge with proto3 and initExtensionField
initFields(target: Message): void {
for (const member of target.getType().fields.byMember()) {
const name = member.localName,
t = target as AnyMessage;
if (member.repeated) {
t[name] = [];
continue;
}
switch (member.kind) {
case "oneof":
t[name] = { case: undefined };
break;
case "map":
t[name] = {};
break;
case "scalar":
case "enum":
case "message":
// In contrast to proto3, enum and scalar fields have no intrinsic default value,
// only an optional explicit default value.
// Unlike proto3 intrinsic default values, proto2 explicit default values are not
// set on construction, because they are not omitted on the wire. If we did set
// default values on construction, a deserialize-serialize round-trip would add
// fields to a message.
break;
}
(fields: FieldListSource): FieldList => {
return new InternalFieldList(fields, (source) =>
normalizeFieldInfos(source, false),
);
},
// TODO merge with proto3 and initExtensionField
(target: Message): void => {
for (const member of target.getType().fields.byMember()) {
const name = member.localName,
t = target as AnyMessage;
if (member.repeated) {
t[name] = [];
continue;
}
switch (member.kind) {
case "oneof":
t[name] = { case: undefined };
break;
case "map":
t[name] = {};
break;
case "scalar":
case "enum":
case "message":
// In contrast to proto3, enum and scalar fields have no intrinsic default value,
// only an optional explicit default value.
// Unlike proto3 intrinsic default values, proto2 explicit default values are not
// set on construction, because they are not omitted on the wire. If we did set
// default values on construction, a deserialize-serialize round-trip would add
// fields to a message.
break;
}
},
}
},
);
76 changes: 34 additions & 42 deletions packages/protobuf/src/proto3.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,60 +13,52 @@
// limitations under the License.

import { makeProtoRuntime } from "./private/proto-runtime.js";
import { makeUtilCommon } from "./private/util-common.js";
import type { FieldListSource } from "./private/field-list.js";
import { InternalFieldList } from "./private/field-list.js";
import type { FieldList } from "./field-list.js";
import type { AnyMessage, Message } from "./message.js";
import { scalarDefaultValue } from "./private/scalars.js";
import { normalizeFieldInfos } from "./private/field-normalize.js";
import { makeBinaryFormat } from "./private/binary-format.js";
import { makeJsonFormat } from "./private/json-format.js";

/**
* Provides functionality for messages defined with the proto3 syntax.
*/
export const proto3 = makeProtoRuntime(
"proto3",
makeJsonFormat(),
makeBinaryFormat(),
{
...makeUtilCommon(),
newFieldList(fields: FieldListSource): FieldList {
return new InternalFieldList(fields, (source) =>
normalizeFieldInfos(source, true),
);
},
// TODO merge with proto2 and initExtensionField
initFields(target: Message): void {
for (const member of target.getType().fields.byMember()) {
if (member.opt) {
continue;
}
const name = member.localName,
t = target as AnyMessage;
if (member.repeated) {
t[name] = [];
continue;
}
switch (member.kind) {
case "oneof":
t[name] = { case: undefined };
break;
case "enum":
t[name] = 0;
break;
case "map":
t[name] = {};
break;
case "scalar":
t[name] = scalarDefaultValue(member.T, member.L); // eslint-disable-line @typescript-eslint/no-unsafe-assignment
break;
case "message":
// message fields are always optional in proto3
break;
}
(fields: FieldListSource): FieldList => {
return new InternalFieldList(fields, (source) =>
normalizeFieldInfos(source, true),
);
},
// TODO merge with proto2 and initExtensionField
(target: Message): void => {
for (const member of target.getType().fields.byMember()) {
if (member.opt) {
continue;
}
const name = member.localName,
t = target as AnyMessage;
if (member.repeated) {
t[name] = [];
continue;
}
switch (member.kind) {
case "oneof":
t[name] = { case: undefined };
break;
case "enum":
t[name] = 0;
break;
case "map":
t[name] = {};
break;
case "scalar":
t[name] = scalarDefaultValue(member.T, member.L); // eslint-disable-line @typescript-eslint/no-unsafe-assignment
break;
case "message":
// message fields are always optional in proto3
break;
}
},
}
},
);

0 comments on commit 235b82c

Please sign in to comment.