@bufbuild/protobuf 1.7.2 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/codegen-info.d.ts +6 -1
- package/dist/cjs/codegen-info.js +4 -3
- package/dist/cjs/create-descriptor-set.js +45 -33
- package/dist/cjs/create-registry-from-desc.js +60 -110
- package/dist/cjs/descriptor-set.d.ts +13 -9
- package/dist/cjs/field.d.ts +25 -51
- package/dist/cjs/field.js +0 -66
- package/dist/cjs/google/protobuf/compiler/plugin_pb.d.ts +18 -0
- package/dist/cjs/google/protobuf/compiler/plugin_pb.js +2 -0
- package/dist/cjs/google/protobuf/descriptor_pb.d.ts +33 -33
- package/dist/cjs/google/protobuf/descriptor_pb.js +23 -10
- package/dist/cjs/google/protobuf/struct_pb.js +1 -1
- package/dist/cjs/google/protobuf/type_pb.js +1 -1
- package/dist/cjs/google/protobuf/wrappers_pb.js +19 -19
- package/dist/cjs/index.d.ts +3 -1
- package/dist/cjs/index.js +6 -4
- package/dist/cjs/is-message.d.ts +22 -0
- package/dist/cjs/is-message.js +52 -0
- package/dist/cjs/json-format.d.ts +1 -2
- package/dist/cjs/private/binary-format.d.ts +7 -0
- package/dist/cjs/private/{binary-format-common.js → binary-format.js} +150 -53
- package/dist/cjs/private/extensions.js +1 -1
- package/dist/cjs/private/feature-set.js +1 -1
- package/dist/cjs/private/field-normalize.d.ts +9 -0
- package/dist/cjs/private/field-normalize.js +69 -0
- package/dist/cjs/private/field-wrapper.d.ts +1 -1
- package/dist/cjs/private/field-wrapper.js +12 -12
- package/dist/cjs/private/field.d.ts +1 -0
- package/dist/cjs/private/field.js +1 -0
- package/dist/cjs/private/json-format.d.ts +2 -0
- package/dist/cjs/private/{json-format-common.js → json-format.js} +261 -170
- package/dist/cjs/private/proto-runtime.d.ts +1 -1
- package/dist/cjs/private/proto-runtime.js +8 -4
- package/dist/cjs/private/reflect.d.ts +9 -0
- package/dist/cjs/private/reflect.js +79 -0
- package/dist/cjs/private/reify-wkt.js +11 -11
- package/dist/cjs/private/scalars.d.ts +9 -18
- package/dist/cjs/private/scalars.js +36 -80
- package/dist/cjs/private/text-format.d.ts +1 -1
- package/dist/cjs/private/text-format.js +17 -17
- package/dist/cjs/private/util-common.js +17 -14
- package/dist/cjs/proto-delimited.js +2 -3
- package/dist/cjs/proto2.js +29 -68
- package/dist/cjs/proto3.js +30 -77
- package/dist/cjs/scalar.d.ts +53 -0
- package/dist/cjs/scalar.js +81 -0
- package/dist/cjs/to-plain-message.js +3 -4
- package/dist/esm/codegen-info.d.ts +6 -1
- package/dist/esm/codegen-info.js +6 -5
- package/dist/esm/create-descriptor-set.js +22 -10
- package/dist/esm/create-registry-from-desc.js +62 -111
- package/dist/esm/descriptor-set.d.ts +13 -9
- package/dist/esm/descriptor-set.js +1 -1
- package/dist/esm/field.d.ts +25 -51
- package/dist/esm/field.js +1 -65
- package/dist/esm/google/protobuf/compiler/plugin_pb.d.ts +18 -0
- package/dist/esm/google/protobuf/compiler/plugin_pb.js +2 -0
- package/dist/esm/google/protobuf/descriptor_pb.d.ts +33 -33
- package/dist/esm/google/protobuf/descriptor_pb.js +23 -10
- package/dist/esm/google/protobuf/struct_pb.js +1 -1
- package/dist/esm/google/protobuf/type_pb.js +1 -1
- package/dist/esm/google/protobuf/wrappers_pb.js +1 -1
- package/dist/esm/index.d.ts +3 -1
- package/dist/esm/index.js +2 -1
- package/dist/esm/is-message.d.ts +22 -0
- package/dist/esm/is-message.js +48 -0
- package/dist/esm/json-format.d.ts +1 -2
- package/dist/esm/json-format.js +1 -1
- package/dist/esm/private/binary-format.d.ts +7 -0
- package/dist/esm/private/{binary-format-common.js → binary-format.js} +126 -25
- package/dist/esm/private/extensions.js +2 -2
- package/dist/esm/private/feature-set.js +1 -1
- package/dist/esm/private/field-normalize.d.ts +9 -0
- package/dist/esm/private/field-normalize.js +65 -0
- package/dist/esm/private/field-wrapper.d.ts +1 -1
- package/dist/esm/private/field-wrapper.js +3 -2
- package/dist/esm/private/field.d.ts +1 -0
- package/dist/esm/private/field.js +1 -0
- package/dist/esm/private/json-format.d.ts +2 -0
- package/dist/esm/private/{json-format-common.js → json-format.js} +227 -135
- package/dist/esm/private/proto-runtime.d.ts +1 -1
- package/dist/esm/private/proto-runtime.js +8 -4
- package/dist/esm/private/reflect.d.ts +9 -0
- package/dist/esm/private/reflect.js +74 -0
- package/dist/esm/private/reify-wkt.js +1 -1
- package/dist/esm/private/scalars.d.ts +9 -18
- package/dist/esm/private/scalars.js +15 -59
- package/dist/esm/private/text-format.d.ts +1 -1
- package/dist/esm/private/text-format.js +1 -1
- package/dist/esm/private/util-common.js +10 -6
- package/dist/esm/proto-delimited.js +2 -3
- package/dist/esm/proto2.js +29 -68
- package/dist/esm/proto3.js +31 -78
- package/dist/esm/scalar.d.ts +53 -0
- package/dist/esm/scalar.js +78 -0
- package/dist/esm/to-plain-message.js +3 -2
- package/package.json +2 -8
- package/dist/cjs/private/binary-format-common.d.ts +0 -13
- package/dist/cjs/private/binary-format-proto2.d.ts +0 -2
- package/dist/cjs/private/binary-format-proto2.js +0 -91
- package/dist/cjs/private/binary-format-proto3.d.ts +0 -2
- package/dist/cjs/private/binary-format-proto3.js +0 -83
- package/dist/cjs/private/json-format-common.d.ts +0 -9
- package/dist/cjs/private/json-format-proto2.d.ts +0 -2
- package/dist/cjs/private/json-format-proto2.js +0 -103
- package/dist/cjs/private/json-format-proto3.d.ts +0 -2
- package/dist/cjs/private/json-format-proto3.js +0 -94
- package/dist/esm/private/binary-format-common.d.ts +0 -13
- package/dist/esm/private/binary-format-proto2.d.ts +0 -2
- package/dist/esm/private/binary-format-proto2.js +0 -87
- package/dist/esm/private/binary-format-proto3.d.ts +0 -2
- package/dist/esm/private/binary-format-proto3.js +0 -79
- package/dist/esm/private/json-format-common.d.ts +0 -9
- package/dist/esm/private/json-format-proto2.d.ts +0 -2
- package/dist/esm/private/json-format-proto2.js +0 -99
- package/dist/esm/private/json-format-proto3.d.ts +0 -2
- package/dist/esm/private/json-format-proto3.js +0 -90
- package/dist/proxy/index.d.ts +0 -1
- package/dist/proxy/index.js +0 -1
|
@@ -12,13 +12,18 @@
|
|
|
12
12
|
// See the License for the specific language governing permissions and
|
|
13
13
|
// limitations under the License.
|
|
14
14
|
import { Message } from "../message.js";
|
|
15
|
-
import { LongType, ScalarType } from "../field.js";
|
|
16
15
|
import { assert, assertFloat32, assertInt32, assertUInt32 } from "./assert.js";
|
|
17
16
|
import { protoInt64 } from "../proto-int64.js";
|
|
18
17
|
import { protoBase64 } from "../proto-base64.js";
|
|
19
18
|
import { createExtensionContainer } from "./extensions.js";
|
|
20
19
|
import { getExtension, hasExtension, setExtension, } from "../extension-accessor.js";
|
|
21
|
-
|
|
20
|
+
import { clearField, isFieldSet } from "./reflect.js";
|
|
21
|
+
import { wrapField } from "./field-wrapper.js";
|
|
22
|
+
import { scalarZeroValue } from "./scalars.js";
|
|
23
|
+
import { isScalarZeroValue } from "./scalars.js";
|
|
24
|
+
import { LongType, ScalarType } from "../scalar.js";
|
|
25
|
+
import { isMessage } from "../is-message.js";
|
|
26
|
+
/* eslint-disable no-case-declarations,@typescript-eslint/no-unsafe-argument,@typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-call */
|
|
22
27
|
// Default options for parsing JSON.
|
|
23
28
|
const jsonReadDefaults = {
|
|
24
29
|
ignoreUnknownFields: false,
|
|
@@ -36,8 +41,9 @@ function makeReadOptions(options) {
|
|
|
36
41
|
function makeWriteOptions(options) {
|
|
37
42
|
return options ? Object.assign(Object.assign({}, jsonWriteDefaults), options) : jsonWriteDefaults;
|
|
38
43
|
}
|
|
39
|
-
|
|
40
|
-
|
|
44
|
+
const tokenNull = Symbol();
|
|
45
|
+
const tokenIgnoredUnknownEnum = Symbol();
|
|
46
|
+
export function makeJsonFormat() {
|
|
41
47
|
return {
|
|
42
48
|
makeReadOptions,
|
|
43
49
|
makeWriteOptions,
|
|
@@ -62,7 +68,7 @@ export function makeJsonFormatCommon(nullAsZeroValue, makeWriteField) {
|
|
|
62
68
|
}
|
|
63
69
|
oneofSeen.set(field.oneof, jsonKey);
|
|
64
70
|
}
|
|
65
|
-
readField(message, jsonValue, field, options, type
|
|
71
|
+
readField(message, jsonValue, field, options, type);
|
|
66
72
|
}
|
|
67
73
|
else {
|
|
68
74
|
let found = false;
|
|
@@ -73,7 +79,7 @@ export function makeJsonFormatCommon(nullAsZeroValue, makeWriteField) {
|
|
|
73
79
|
if (ext && ext.extendee.typeName == type.typeName) {
|
|
74
80
|
found = true;
|
|
75
81
|
const [container, get] = createExtensionContainer(ext);
|
|
76
|
-
readField(container, jsonValue, ext.field, options, ext
|
|
82
|
+
readField(container, jsonValue, ext.field, options, ext);
|
|
77
83
|
// We pass on the options as BinaryReadOptions/BinaryWriteOptions,
|
|
78
84
|
// so that users can bring their own binary reader and writer factories
|
|
79
85
|
// if necessary.
|
|
@@ -92,23 +98,23 @@ export function makeJsonFormatCommon(nullAsZeroValue, makeWriteField) {
|
|
|
92
98
|
const json = {};
|
|
93
99
|
let field;
|
|
94
100
|
try {
|
|
95
|
-
for (
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
101
|
+
for (field of type.fields.byNumber()) {
|
|
102
|
+
if (!isFieldSet(field, message)) {
|
|
103
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
104
|
+
if (field.req) {
|
|
105
|
+
throw `required field not set`;
|
|
106
|
+
}
|
|
107
|
+
if (!options.emitDefaultValues) {
|
|
100
108
|
continue;
|
|
101
109
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
throw "oneof case not found: " + oneof.case;
|
|
110
|
+
if (!canEmitFieldDefaultValue(field)) {
|
|
111
|
+
continue;
|
|
105
112
|
}
|
|
106
|
-
jsonValue = writeField(field, oneof.value, options);
|
|
107
|
-
}
|
|
108
|
-
else {
|
|
109
|
-
field = member;
|
|
110
|
-
jsonValue = writeField(field, message[field.localName], options);
|
|
111
113
|
}
|
|
114
|
+
const value = field.oneof
|
|
115
|
+
? message[field.oneof.localName].value
|
|
116
|
+
: message[field.localName];
|
|
117
|
+
const jsonValue = writeField(field, value, options);
|
|
112
118
|
if (jsonValue !== undefined) {
|
|
113
119
|
json[options.useProtoFieldName ? field.name : field.jsonName] =
|
|
114
120
|
jsonValue;
|
|
@@ -139,8 +145,24 @@ export function makeJsonFormatCommon(nullAsZeroValue, makeWriteField) {
|
|
|
139
145
|
}
|
|
140
146
|
return json;
|
|
141
147
|
},
|
|
142
|
-
readScalar
|
|
143
|
-
|
|
148
|
+
readScalar(type, json, longType) {
|
|
149
|
+
// The signature of our internal function has changed. For backwards-
|
|
150
|
+
// compatibility, we support the old form that is part of the public API
|
|
151
|
+
// through the interface JsonFormat.
|
|
152
|
+
return readScalar(type, json, longType !== null && longType !== void 0 ? longType : LongType.BIGINT, true);
|
|
153
|
+
},
|
|
154
|
+
writeScalar(type, value, emitDefaultValues) {
|
|
155
|
+
// The signature of our internal function has changed. For backwards-
|
|
156
|
+
// compatibility, we support the old form that is part of the public API
|
|
157
|
+
// through the interface JsonFormat.
|
|
158
|
+
if (value === undefined) {
|
|
159
|
+
return undefined;
|
|
160
|
+
}
|
|
161
|
+
if (emitDefaultValues || isScalarZeroValue(type, value)) {
|
|
162
|
+
return writeScalar(type, value);
|
|
163
|
+
}
|
|
164
|
+
return undefined;
|
|
165
|
+
},
|
|
144
166
|
debug: debugJsonValue,
|
|
145
167
|
};
|
|
146
168
|
}
|
|
@@ -158,50 +180,38 @@ function debugJsonValue(json) {
|
|
|
158
180
|
}
|
|
159
181
|
}
|
|
160
182
|
// Read a JSON value for a field.
|
|
161
|
-
// The "
|
|
162
|
-
|
|
163
|
-
// or oneof). If the argument is `true`, JSON null is parsed as the fields
|
|
164
|
-
// zero-value. If the argument is false, JSON null sets the field to `undefined`.
|
|
165
|
-
function readField(target, // eslint-disable-line @typescript-eslint/no-explicit-any -- `any` is the best choice for dynamic access
|
|
166
|
-
jsonValue, field, options, type, nullAsZeroValue) {
|
|
183
|
+
// The "parentType" argument is only used to provide context in errors.
|
|
184
|
+
function readField(target, jsonValue, field, options, parentType) {
|
|
167
185
|
let localName = field.localName;
|
|
168
|
-
if (field.oneof) {
|
|
169
|
-
if (jsonValue === null && field.kind == "scalar") {
|
|
170
|
-
// see conformance test Required.Proto3.JsonInput.OneofFieldNull{First,Second}
|
|
171
|
-
return;
|
|
172
|
-
}
|
|
173
|
-
target = target[field.oneof.localName] = { case: localName };
|
|
174
|
-
localName = "value";
|
|
175
|
-
}
|
|
176
186
|
if (field.repeated) {
|
|
187
|
+
assert(field.kind != "map");
|
|
177
188
|
if (jsonValue === null) {
|
|
178
189
|
return;
|
|
179
190
|
}
|
|
180
191
|
if (!Array.isArray(jsonValue)) {
|
|
181
|
-
throw new Error(`cannot decode field ${
|
|
192
|
+
throw new Error(`cannot decode field ${parentType.typeName}.${field.name} from JSON: ${debugJsonValue(jsonValue)}`);
|
|
182
193
|
}
|
|
183
194
|
const targetArray = target[localName];
|
|
184
195
|
for (const jsonItem of jsonValue) {
|
|
185
196
|
if (jsonItem === null) {
|
|
186
|
-
throw new Error(`cannot decode field ${
|
|
197
|
+
throw new Error(`cannot decode field ${parentType.typeName}.${field.name} from JSON: ${debugJsonValue(jsonItem)}`);
|
|
187
198
|
}
|
|
188
|
-
let val;
|
|
189
|
-
// eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check -- "map" is invalid for repeated fields
|
|
190
199
|
switch (field.kind) {
|
|
191
200
|
case "message":
|
|
192
|
-
|
|
201
|
+
targetArray.push(field.T.fromJson(jsonItem, options));
|
|
193
202
|
break;
|
|
194
203
|
case "enum":
|
|
195
|
-
|
|
196
|
-
if (
|
|
197
|
-
|
|
204
|
+
const enumValue = readEnum(field.T, jsonItem, options.ignoreUnknownFields, true);
|
|
205
|
+
if (enumValue !== tokenIgnoredUnknownEnum) {
|
|
206
|
+
targetArray.push(enumValue);
|
|
207
|
+
}
|
|
198
208
|
break;
|
|
199
209
|
case "scalar":
|
|
200
210
|
try {
|
|
201
|
-
|
|
211
|
+
targetArray.push(readScalar(field.T, jsonItem, field.L, true));
|
|
202
212
|
}
|
|
203
213
|
catch (e) {
|
|
204
|
-
let m = `cannot decode field ${
|
|
214
|
+
let m = `cannot decode field ${parentType.typeName}.${field.name} from JSON: ${debugJsonValue(jsonItem)}`;
|
|
205
215
|
if (e instanceof Error && e.message.length > 0) {
|
|
206
216
|
m += `: ${e.message}`;
|
|
207
217
|
}
|
|
@@ -209,7 +219,6 @@ jsonValue, field, options, type, nullAsZeroValue) {
|
|
|
209
219
|
}
|
|
210
220
|
break;
|
|
211
221
|
}
|
|
212
|
-
targetArray.push(val);
|
|
213
222
|
}
|
|
214
223
|
}
|
|
215
224
|
else if (field.kind == "map") {
|
|
@@ -217,29 +226,40 @@ jsonValue, field, options, type, nullAsZeroValue) {
|
|
|
217
226
|
return;
|
|
218
227
|
}
|
|
219
228
|
if (typeof jsonValue != "object" || Array.isArray(jsonValue)) {
|
|
220
|
-
throw new Error(`cannot decode field ${
|
|
229
|
+
throw new Error(`cannot decode field ${parentType.typeName}.${field.name} from JSON: ${debugJsonValue(jsonValue)}`);
|
|
221
230
|
}
|
|
222
231
|
const targetMap = target[localName];
|
|
223
232
|
for (const [jsonMapKey, jsonMapValue] of Object.entries(jsonValue)) {
|
|
224
233
|
if (jsonMapValue === null) {
|
|
225
|
-
throw new Error(`cannot decode field ${
|
|
234
|
+
throw new Error(`cannot decode field ${parentType.typeName}.${field.name} from JSON: map value null`);
|
|
235
|
+
}
|
|
236
|
+
let key;
|
|
237
|
+
try {
|
|
238
|
+
key = readMapKey(field.K, jsonMapKey);
|
|
239
|
+
}
|
|
240
|
+
catch (e) {
|
|
241
|
+
let m = `cannot decode map key for field ${parentType.typeName}.${field.name} from JSON: ${debugJsonValue(jsonValue)}`;
|
|
242
|
+
if (e instanceof Error && e.message.length > 0) {
|
|
243
|
+
m += `: ${e.message}`;
|
|
244
|
+
}
|
|
245
|
+
throw new Error(m);
|
|
226
246
|
}
|
|
227
|
-
let val;
|
|
228
247
|
switch (field.V.kind) {
|
|
229
248
|
case "message":
|
|
230
|
-
|
|
249
|
+
targetMap[key] = field.V.T.fromJson(jsonMapValue, options);
|
|
231
250
|
break;
|
|
232
251
|
case "enum":
|
|
233
|
-
|
|
234
|
-
if (
|
|
235
|
-
|
|
252
|
+
const enumValue = readEnum(field.V.T, jsonMapValue, options.ignoreUnknownFields, true);
|
|
253
|
+
if (enumValue !== tokenIgnoredUnknownEnum) {
|
|
254
|
+
targetMap[key] = enumValue;
|
|
255
|
+
}
|
|
236
256
|
break;
|
|
237
257
|
case "scalar":
|
|
238
258
|
try {
|
|
239
|
-
|
|
259
|
+
targetMap[key] = readScalar(field.V.T, jsonMapValue, LongType.BIGINT, true);
|
|
240
260
|
}
|
|
241
261
|
catch (e) {
|
|
242
|
-
let m = `cannot decode map value for field ${
|
|
262
|
+
let m = `cannot decode map value for field ${parentType.typeName}.${field.name} from JSON: ${debugJsonValue(jsonValue)}`;
|
|
243
263
|
if (e instanceof Error && e.message.length > 0) {
|
|
244
264
|
m += `: ${e.message}`;
|
|
245
265
|
}
|
|
@@ -247,57 +267,59 @@ jsonValue, field, options, type, nullAsZeroValue) {
|
|
|
247
267
|
}
|
|
248
268
|
break;
|
|
249
269
|
}
|
|
250
|
-
try {
|
|
251
|
-
targetMap[readScalar(field.K, field.K == ScalarType.BOOL
|
|
252
|
-
? jsonMapKey == "true"
|
|
253
|
-
? true
|
|
254
|
-
: jsonMapKey == "false"
|
|
255
|
-
? false
|
|
256
|
-
: jsonMapKey
|
|
257
|
-
: jsonMapKey, LongType.BIGINT, true).toString()] = val;
|
|
258
|
-
}
|
|
259
|
-
catch (e) {
|
|
260
|
-
let m = `cannot decode map key for field ${type.typeName}.${field.name} from JSON: ${debugJsonValue(jsonValue)}`;
|
|
261
|
-
if (e instanceof Error && e.message.length > 0) {
|
|
262
|
-
m += `: ${e.message}`;
|
|
263
|
-
}
|
|
264
|
-
throw new Error(m);
|
|
265
|
-
}
|
|
266
270
|
}
|
|
267
271
|
}
|
|
268
272
|
else {
|
|
273
|
+
if (field.oneof) {
|
|
274
|
+
target = target[field.oneof.localName] = { case: localName };
|
|
275
|
+
localName = "value";
|
|
276
|
+
}
|
|
269
277
|
switch (field.kind) {
|
|
270
278
|
case "message":
|
|
271
279
|
const messageType = field.T;
|
|
272
280
|
if (jsonValue === null &&
|
|
273
281
|
messageType.typeName != "google.protobuf.Value") {
|
|
274
|
-
if (field.oneof) {
|
|
275
|
-
throw new Error(`cannot decode field ${type.typeName}.${field.name} from JSON: null is invalid for oneof field`);
|
|
276
|
-
}
|
|
277
282
|
return;
|
|
278
283
|
}
|
|
279
|
-
|
|
280
|
-
|
|
284
|
+
let currentValue = target[localName];
|
|
285
|
+
if (isMessage(currentValue)) {
|
|
286
|
+
currentValue.fromJson(jsonValue, options);
|
|
281
287
|
}
|
|
282
288
|
else {
|
|
283
|
-
target[localName] = messageType.fromJson(jsonValue, options);
|
|
289
|
+
target[localName] = currentValue = messageType.fromJson(jsonValue, options);
|
|
284
290
|
if (messageType.fieldWrapper && !field.oneof) {
|
|
285
|
-
target[localName] =
|
|
291
|
+
target[localName] =
|
|
292
|
+
messageType.fieldWrapper.unwrapField(currentValue);
|
|
286
293
|
}
|
|
287
294
|
}
|
|
288
295
|
break;
|
|
289
296
|
case "enum":
|
|
290
|
-
const enumValue = readEnum(field.T, jsonValue, options.ignoreUnknownFields,
|
|
291
|
-
|
|
292
|
-
|
|
297
|
+
const enumValue = readEnum(field.T, jsonValue, options.ignoreUnknownFields, false);
|
|
298
|
+
switch (enumValue) {
|
|
299
|
+
case tokenNull:
|
|
300
|
+
clearField(field, target);
|
|
301
|
+
break;
|
|
302
|
+
case tokenIgnoredUnknownEnum:
|
|
303
|
+
break;
|
|
304
|
+
default:
|
|
305
|
+
target[localName] = enumValue;
|
|
306
|
+
break;
|
|
293
307
|
}
|
|
294
308
|
break;
|
|
295
309
|
case "scalar":
|
|
296
310
|
try {
|
|
297
|
-
|
|
311
|
+
const scalarValue = readScalar(field.T, jsonValue, field.L, false);
|
|
312
|
+
switch (scalarValue) {
|
|
313
|
+
case tokenNull:
|
|
314
|
+
clearField(field, target);
|
|
315
|
+
break;
|
|
316
|
+
default:
|
|
317
|
+
target[localName] = scalarValue;
|
|
318
|
+
break;
|
|
319
|
+
}
|
|
298
320
|
}
|
|
299
321
|
catch (e) {
|
|
300
|
-
let m = `cannot decode field ${
|
|
322
|
+
let m = `cannot decode field ${parentType.typeName}.${field.name} from JSON: ${debugJsonValue(jsonValue)}`;
|
|
301
323
|
if (e instanceof Error && e.message.length > 0) {
|
|
302
324
|
m += `: ${e.message}`;
|
|
303
325
|
}
|
|
@@ -307,12 +329,27 @@ jsonValue, field, options, type, nullAsZeroValue) {
|
|
|
307
329
|
}
|
|
308
330
|
}
|
|
309
331
|
}
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
//
|
|
313
|
-
|
|
314
|
-
|
|
332
|
+
function readMapKey(type, json) {
|
|
333
|
+
if (type === ScalarType.BOOL) {
|
|
334
|
+
// eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check
|
|
335
|
+
switch (json) {
|
|
336
|
+
case "true":
|
|
337
|
+
json = true;
|
|
338
|
+
break;
|
|
339
|
+
case "false":
|
|
340
|
+
json = false;
|
|
341
|
+
break;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
return readScalar(type, json, LongType.BIGINT, true).toString();
|
|
345
|
+
}
|
|
315
346
|
function readScalar(type, json, longType, nullAsZeroValue) {
|
|
347
|
+
if (json === null) {
|
|
348
|
+
if (nullAsZeroValue) {
|
|
349
|
+
return scalarZeroValue(type, longType);
|
|
350
|
+
}
|
|
351
|
+
return tokenNull;
|
|
352
|
+
}
|
|
316
353
|
// every valid case in the switch below returns, and every fall
|
|
317
354
|
// through is regarded as a failure.
|
|
318
355
|
switch (type) {
|
|
@@ -320,8 +357,6 @@ function readScalar(type, json, longType, nullAsZeroValue) {
|
|
|
320
357
|
// Either numbers or strings are accepted. Exponent notation is also accepted.
|
|
321
358
|
case ScalarType.DOUBLE:
|
|
322
359
|
case ScalarType.FLOAT:
|
|
323
|
-
if (json === null)
|
|
324
|
-
return nullAsZeroValue ? 0.0 : undefined;
|
|
325
360
|
if (json === "NaN")
|
|
326
361
|
return Number.NaN;
|
|
327
362
|
if (json === "Infinity")
|
|
@@ -357,8 +392,6 @@ function readScalar(type, json, longType, nullAsZeroValue) {
|
|
|
357
392
|
case ScalarType.SFIXED32:
|
|
358
393
|
case ScalarType.SINT32:
|
|
359
394
|
case ScalarType.UINT32:
|
|
360
|
-
if (json === null)
|
|
361
|
-
return nullAsZeroValue ? 0 : undefined;
|
|
362
395
|
let int32;
|
|
363
396
|
if (typeof json == "number")
|
|
364
397
|
int32 = json;
|
|
@@ -377,8 +410,6 @@ function readScalar(type, json, longType, nullAsZeroValue) {
|
|
|
377
410
|
case ScalarType.INT64:
|
|
378
411
|
case ScalarType.SFIXED64:
|
|
379
412
|
case ScalarType.SINT64:
|
|
380
|
-
if (json === null)
|
|
381
|
-
return nullAsZeroValue ? protoInt64.zero : undefined;
|
|
382
413
|
if (typeof json != "number" && typeof json != "string")
|
|
383
414
|
break;
|
|
384
415
|
const long = protoInt64.parse(json);
|
|
@@ -386,8 +417,6 @@ function readScalar(type, json, longType, nullAsZeroValue) {
|
|
|
386
417
|
return longType ? long.toString() : long;
|
|
387
418
|
case ScalarType.FIXED64:
|
|
388
419
|
case ScalarType.UINT64:
|
|
389
|
-
if (json === null)
|
|
390
|
-
return nullAsZeroValue ? protoInt64.zero : undefined;
|
|
391
420
|
if (typeof json != "number" && typeof json != "string")
|
|
392
421
|
break;
|
|
393
422
|
const uLong = protoInt64.uParse(json);
|
|
@@ -395,15 +424,11 @@ function readScalar(type, json, longType, nullAsZeroValue) {
|
|
|
395
424
|
return longType ? uLong.toString() : uLong;
|
|
396
425
|
// bool:
|
|
397
426
|
case ScalarType.BOOL:
|
|
398
|
-
if (json === null)
|
|
399
|
-
return nullAsZeroValue ? false : undefined;
|
|
400
427
|
if (typeof json !== "boolean")
|
|
401
428
|
break;
|
|
402
429
|
return json;
|
|
403
430
|
// string:
|
|
404
431
|
case ScalarType.STRING:
|
|
405
|
-
if (json === null)
|
|
406
|
-
return nullAsZeroValue ? "" : undefined;
|
|
407
432
|
if (typeof json !== "string") {
|
|
408
433
|
break;
|
|
409
434
|
}
|
|
@@ -419,8 +444,6 @@ function readScalar(type, json, longType, nullAsZeroValue) {
|
|
|
419
444
|
// bytes: JSON value will be the data encoded as a string using standard base64 encoding with paddings.
|
|
420
445
|
// Either standard or URL-safe base64 encoding with/without paddings are accepted.
|
|
421
446
|
case ScalarType.BYTES:
|
|
422
|
-
if (json === null)
|
|
423
|
-
return nullAsZeroValue ? new Uint8Array(0) : undefined;
|
|
424
447
|
if (json === "")
|
|
425
448
|
return new Uint8Array(0);
|
|
426
449
|
if (typeof json !== "string")
|
|
@@ -429,14 +452,12 @@ function readScalar(type, json, longType, nullAsZeroValue) {
|
|
|
429
452
|
}
|
|
430
453
|
throw new Error();
|
|
431
454
|
}
|
|
432
|
-
// If the argument "nullAsZeroValue" is `true`, this function returns the first
|
|
433
|
-
// enum value for JSON null. If the argument is `false`, this function returns
|
|
434
|
-
// `undefined`.
|
|
435
455
|
function readEnum(type, json, ignoreUnknownFields, nullAsZeroValue) {
|
|
436
456
|
if (json === null) {
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
457
|
+
if (type.typeName == "google.protobuf.NullValue") {
|
|
458
|
+
return 0; // google.protobuf.NullValue.NULL_VALUE = 0
|
|
459
|
+
}
|
|
460
|
+
return nullAsZeroValue ? type.values[0].no : tokenNull;
|
|
440
461
|
}
|
|
441
462
|
// eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check
|
|
442
463
|
switch (typeof json) {
|
|
@@ -447,36 +468,112 @@ function readEnum(type, json, ignoreUnknownFields, nullAsZeroValue) {
|
|
|
447
468
|
break;
|
|
448
469
|
case "string":
|
|
449
470
|
const value = type.findName(json);
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
471
|
+
if (value !== undefined) {
|
|
472
|
+
return value.no;
|
|
473
|
+
}
|
|
474
|
+
if (ignoreUnknownFields) {
|
|
475
|
+
return tokenIgnoredUnknownEnum;
|
|
453
476
|
}
|
|
454
477
|
break;
|
|
455
478
|
}
|
|
456
479
|
throw new Error(`cannot decode enum ${type.typeName} from JSON: ${debugJsonValue(json)}`);
|
|
457
480
|
}
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
if (
|
|
461
|
-
|
|
481
|
+
// Decide whether an unset field should be emitted with JSON write option `emitDefaultValues`
|
|
482
|
+
function canEmitFieldDefaultValue(field) {
|
|
483
|
+
if (field.repeated || field.kind == "map") {
|
|
484
|
+
// maps are {}, repeated fields are []
|
|
485
|
+
return true;
|
|
486
|
+
}
|
|
487
|
+
if (field.oneof) {
|
|
488
|
+
// oneof fields are never emitted
|
|
489
|
+
return false;
|
|
462
490
|
}
|
|
463
|
-
if (
|
|
464
|
-
//
|
|
465
|
-
return
|
|
491
|
+
if (field.kind == "message") {
|
|
492
|
+
// singular message field are allowed to emit JSON null, but we do not
|
|
493
|
+
return false;
|
|
466
494
|
}
|
|
467
|
-
|
|
468
|
-
|
|
495
|
+
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
496
|
+
if (field.opt || field.req) {
|
|
497
|
+
// the field uses explicit presence, so we cannot emit a zero value
|
|
498
|
+
return false;
|
|
499
|
+
}
|
|
500
|
+
return true;
|
|
501
|
+
}
|
|
502
|
+
function writeField(field, value, options) {
|
|
503
|
+
if (field.kind == "map") {
|
|
504
|
+
assert(typeof value == "object" && value != null);
|
|
505
|
+
const jsonObj = {};
|
|
506
|
+
const entries = Object.entries(value);
|
|
507
|
+
switch (field.V.kind) {
|
|
508
|
+
case "scalar":
|
|
509
|
+
for (const [entryKey, entryValue] of entries) {
|
|
510
|
+
jsonObj[entryKey.toString()] = writeScalar(field.V.T, entryValue); // JSON standard allows only (double quoted) string as property key
|
|
511
|
+
}
|
|
512
|
+
break;
|
|
513
|
+
case "message":
|
|
514
|
+
for (const [entryKey, entryValue] of entries) {
|
|
515
|
+
// JSON standard allows only (double quoted) string as property key
|
|
516
|
+
jsonObj[entryKey.toString()] = entryValue.toJson(options);
|
|
517
|
+
}
|
|
518
|
+
break;
|
|
519
|
+
case "enum":
|
|
520
|
+
const enumType = field.V.T;
|
|
521
|
+
for (const [entryKey, entryValue] of entries) {
|
|
522
|
+
// JSON standard allows only (double quoted) string as property key
|
|
523
|
+
jsonObj[entryKey.toString()] = writeEnum(enumType, entryValue, options.enumAsInteger);
|
|
524
|
+
}
|
|
525
|
+
break;
|
|
526
|
+
}
|
|
527
|
+
return options.emitDefaultValues || entries.length > 0
|
|
528
|
+
? jsonObj
|
|
529
|
+
: undefined;
|
|
469
530
|
}
|
|
531
|
+
if (field.repeated) {
|
|
532
|
+
assert(Array.isArray(value));
|
|
533
|
+
const jsonArr = [];
|
|
534
|
+
switch (field.kind) {
|
|
535
|
+
case "scalar":
|
|
536
|
+
for (let i = 0; i < value.length; i++) {
|
|
537
|
+
jsonArr.push(writeScalar(field.T, value[i]));
|
|
538
|
+
}
|
|
539
|
+
break;
|
|
540
|
+
case "enum":
|
|
541
|
+
for (let i = 0; i < value.length; i++) {
|
|
542
|
+
jsonArr.push(writeEnum(field.T, value[i], options.enumAsInteger));
|
|
543
|
+
}
|
|
544
|
+
break;
|
|
545
|
+
case "message":
|
|
546
|
+
for (let i = 0; i < value.length; i++) {
|
|
547
|
+
jsonArr.push(value[i].toJson(options));
|
|
548
|
+
}
|
|
549
|
+
break;
|
|
550
|
+
}
|
|
551
|
+
return options.emitDefaultValues || jsonArr.length > 0
|
|
552
|
+
? jsonArr
|
|
553
|
+
: undefined;
|
|
554
|
+
}
|
|
555
|
+
switch (field.kind) {
|
|
556
|
+
case "scalar":
|
|
557
|
+
return writeScalar(field.T, value);
|
|
558
|
+
case "enum":
|
|
559
|
+
return writeEnum(field.T, value, options.enumAsInteger);
|
|
560
|
+
case "message":
|
|
561
|
+
return wrapField(field.T, value).toJson(options);
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
function writeEnum(type, value, enumAsInteger) {
|
|
565
|
+
var _a;
|
|
566
|
+
assert(typeof value == "number");
|
|
470
567
|
if (type.typeName == "google.protobuf.NullValue") {
|
|
471
568
|
return null;
|
|
472
569
|
}
|
|
570
|
+
if (enumAsInteger) {
|
|
571
|
+
return value;
|
|
572
|
+
}
|
|
473
573
|
const val = type.findNumber(value);
|
|
474
574
|
return (_a = val === null || val === void 0 ? void 0 : val.name) !== null && _a !== void 0 ? _a : value; // if we don't know the enum value, just return the number
|
|
475
575
|
}
|
|
476
|
-
function writeScalar(type, value
|
|
477
|
-
if (value === undefined) {
|
|
478
|
-
return undefined;
|
|
479
|
-
}
|
|
576
|
+
function writeScalar(type, value) {
|
|
480
577
|
switch (type) {
|
|
481
578
|
// int32, fixed32, uint32: JSON value will be a decimal number. Either numbers or strings are accepted.
|
|
482
579
|
case ScalarType.INT32:
|
|
@@ -485,7 +582,7 @@ function writeScalar(type, value, emitZeroValue) {
|
|
|
485
582
|
case ScalarType.FIXED32:
|
|
486
583
|
case ScalarType.UINT32:
|
|
487
584
|
assert(typeof value == "number");
|
|
488
|
-
return value
|
|
585
|
+
return value;
|
|
489
586
|
// float, double: JSON value will be a number or one of the special string values "NaN", "Infinity", and "-Infinity".
|
|
490
587
|
// Either numbers or strings are accepted. Exponent notation is also accepted.
|
|
491
588
|
case ScalarType.FLOAT:
|
|
@@ -498,15 +595,15 @@ function writeScalar(type, value, emitZeroValue) {
|
|
|
498
595
|
return "Infinity";
|
|
499
596
|
if (value === Number.NEGATIVE_INFINITY)
|
|
500
597
|
return "-Infinity";
|
|
501
|
-
return value
|
|
598
|
+
return value;
|
|
502
599
|
// string:
|
|
503
600
|
case ScalarType.STRING:
|
|
504
601
|
assert(typeof value == "string");
|
|
505
|
-
return value
|
|
602
|
+
return value;
|
|
506
603
|
// bool:
|
|
507
604
|
case ScalarType.BOOL:
|
|
508
605
|
assert(typeof value == "boolean");
|
|
509
|
-
return value
|
|
606
|
+
return value;
|
|
510
607
|
// JSON value will be a decimal string. Either numbers or strings are accepted.
|
|
511
608
|
case ScalarType.UINT64:
|
|
512
609
|
case ScalarType.FIXED64:
|
|
@@ -516,16 +613,11 @@ function writeScalar(type, value, emitZeroValue) {
|
|
|
516
613
|
assert(typeof value == "bigint" ||
|
|
517
614
|
typeof value == "string" ||
|
|
518
615
|
typeof value == "number");
|
|
519
|
-
|
|
520
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
521
|
-
// @ts-ignore
|
|
522
|
-
return emitZeroValue || value != 0 ? value.toString(10) : undefined;
|
|
616
|
+
return value.toString();
|
|
523
617
|
// bytes: JSON value will be the data encoded as a string using standard base64 encoding with paddings.
|
|
524
618
|
// Either standard or URL-safe base64 encoding with/without paddings are accepted.
|
|
525
619
|
case ScalarType.BYTES:
|
|
526
620
|
assert(value instanceof Uint8Array);
|
|
527
|
-
return
|
|
528
|
-
? protoBase64.enc(value)
|
|
529
|
-
: undefined;
|
|
621
|
+
return protoBase64.enc(value);
|
|
530
622
|
}
|
|
531
623
|
}
|
|
@@ -50,4 +50,4 @@ export interface ProtoRuntime {
|
|
|
50
50
|
*/
|
|
51
51
|
makeExtension<E extends Message<E> = AnyMessage, V = unknown>(typeName: string, extendee: MessageType<E>, field: ExtensionFieldSource): Extension<E, V>;
|
|
52
52
|
}
|
|
53
|
-
export declare function makeProtoRuntime(syntax: string,
|
|
53
|
+
export declare function makeProtoRuntime(syntax: string, newFieldList: Util["newFieldList"], initFields: Util["initFields"]): ProtoRuntime;
|
|
@@ -14,12 +14,16 @@
|
|
|
14
14
|
import { getEnumType, makeEnum, makeEnumType } from "./enum.js";
|
|
15
15
|
import { makeMessageType } from "./message-type.js";
|
|
16
16
|
import { makeExtension } from "./extensions.js";
|
|
17
|
-
|
|
17
|
+
import { makeJsonFormat } from "./json-format.js";
|
|
18
|
+
import { makeBinaryFormat } from "./binary-format.js";
|
|
19
|
+
import { makeUtilCommon } from "./util-common.js";
|
|
20
|
+
export function makeProtoRuntime(syntax, newFieldList, initFields) {
|
|
18
21
|
return {
|
|
19
22
|
syntax,
|
|
20
|
-
json,
|
|
21
|
-
bin,
|
|
22
|
-
util,
|
|
23
|
+
json: makeJsonFormat(),
|
|
24
|
+
bin: makeBinaryFormat(),
|
|
25
|
+
util: Object.assign(Object.assign({}, makeUtilCommon()), { newFieldList,
|
|
26
|
+
initFields }),
|
|
23
27
|
makeMessageType(typeName, fields, opt) {
|
|
24
28
|
return makeMessageType(this, typeName, fields, opt);
|
|
25
29
|
},
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { FieldInfo } from "../field.js";
|
|
2
|
+
/**
|
|
3
|
+
* Returns true if the field is set.
|
|
4
|
+
*/
|
|
5
|
+
export declare function isFieldSet(field: FieldInfo, target: Record<string, any>): boolean;
|
|
6
|
+
/**
|
|
7
|
+
* Resets the field, so that isFieldSet() will return false.
|
|
8
|
+
*/
|
|
9
|
+
export declare function clearField(field: FieldInfo, target: Record<string, any>): void;
|