@bufbuild/protobuf 1.6.0 → 1.7.1
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/binary-encoding.js +2 -3
- package/dist/cjs/binary-format.d.ts +17 -0
- package/dist/cjs/binary-format.js +1 -1
- package/dist/cjs/codegen-info.d.ts +4 -4
- package/dist/cjs/codegen-info.js +2 -1
- package/dist/cjs/create-descriptor-set.d.ts +7 -1
- package/dist/cjs/create-descriptor-set.js +56 -50
- package/dist/cjs/create-registry-from-desc.d.ts +2 -2
- package/dist/cjs/create-registry-from-desc.js +53 -9
- package/dist/cjs/create-registry.d.ts +3 -2
- package/dist/cjs/create-registry.js +56 -37
- package/dist/cjs/descriptor-set.js +1 -1
- package/dist/cjs/enum.js +1 -1
- package/dist/cjs/extension-accessor.d.ts +35 -0
- package/dist/cjs/extension-accessor.js +108 -0
- package/dist/cjs/extension.d.ts +24 -0
- package/dist/cjs/extension.js +15 -0
- package/dist/cjs/field-list.js +1 -1
- package/dist/cjs/field.js +1 -1
- package/dist/cjs/google/protobuf/any_pb.js +1 -1
- package/dist/cjs/google/protobuf/api_pb.js +1 -1
- package/dist/cjs/google/protobuf/compiler/plugin_pb.js +1 -1
- package/dist/cjs/google/protobuf/descriptor_pb.js +2 -2
- package/dist/cjs/google/protobuf/duration_pb.js +1 -1
- package/dist/cjs/google/protobuf/empty_pb.js +1 -1
- package/dist/cjs/google/protobuf/field_mask_pb.js +1 -1
- package/dist/cjs/google/protobuf/source_context_pb.js +1 -1
- package/dist/cjs/google/protobuf/struct_pb.js +2 -2
- package/dist/cjs/google/protobuf/timestamp_pb.js +1 -1
- package/dist/cjs/google/protobuf/type_pb.js +2 -2
- package/dist/cjs/google/protobuf/wrappers_pb.js +1 -1
- package/dist/cjs/index.d.ts +3 -1
- package/dist/cjs/index.js +7 -2
- package/dist/cjs/json-format.d.ts +5 -5
- package/dist/cjs/json-format.js +1 -1
- package/dist/cjs/message-type.js +1 -1
- package/dist/cjs/message.js +1 -1
- package/dist/cjs/private/assert.js +1 -1
- package/dist/cjs/private/binary-format-common.d.ts +2 -3
- package/dist/cjs/private/binary-format-common.js +80 -78
- package/dist/cjs/private/binary-format-proto2.js +59 -64
- package/dist/cjs/private/binary-format-proto3.js +44 -40
- package/dist/cjs/private/enum.js +1 -1
- package/dist/cjs/private/extensions.d.ts +34 -0
- package/dist/cjs/private/extensions.js +86 -0
- package/dist/cjs/private/feature-set.d.ts +6 -8
- package/dist/cjs/private/feature-set.js +41 -42
- package/dist/cjs/private/field-list.js +1 -1
- package/dist/cjs/private/field-wrapper.d.ts +2 -2
- package/dist/cjs/private/field-wrapper.js +1 -1
- package/dist/cjs/private/field.js +1 -1
- package/dist/cjs/private/json-format-common.d.ts +3 -3
- package/dist/cjs/private/json-format-common.js +228 -173
- package/dist/cjs/private/json-format-proto2.js +3 -2
- package/dist/cjs/private/json-format-proto3.js +8 -6
- package/dist/cjs/private/message-type.js +1 -1
- package/dist/cjs/private/names.d.ts +2 -2
- package/dist/cjs/private/names.js +3 -2
- package/dist/cjs/private/options-map.js +1 -1
- package/dist/cjs/private/proto-runtime.d.ts +6 -0
- package/dist/cjs/private/proto-runtime.js +5 -1
- package/dist/cjs/private/reify-wkt.js +1 -1
- package/dist/cjs/private/scalars.js +1 -1
- package/dist/cjs/private/text-format.js +1 -1
- package/dist/cjs/private/util-common.js +1 -1
- package/dist/cjs/private/util.js +1 -1
- package/dist/cjs/proto-base64.js +1 -1
- package/dist/cjs/proto-delimited.js +1 -1
- package/dist/cjs/proto-double.js +1 -1
- package/dist/cjs/proto-int64.js +1 -1
- package/dist/cjs/proto2.js +1 -1
- package/dist/cjs/proto3.js +1 -1
- package/dist/cjs/service-type.js +1 -1
- package/dist/cjs/to-plain-message.js +1 -1
- package/dist/cjs/type-registry.d.ts +14 -0
- package/dist/cjs/type-registry.js +1 -1
- package/dist/esm/binary-encoding.js +2 -3
- package/dist/esm/binary-format.d.ts +17 -0
- package/dist/esm/binary-format.js +1 -1
- package/dist/esm/codegen-info.d.ts +4 -4
- package/dist/esm/codegen-info.js +2 -1
- package/dist/esm/create-descriptor-set.d.ts +7 -1
- package/dist/esm/create-descriptor-set.js +57 -51
- package/dist/esm/create-registry-from-desc.d.ts +2 -2
- package/dist/esm/create-registry-from-desc.js +53 -9
- package/dist/esm/create-registry.d.ts +3 -2
- package/dist/esm/create-registry.js +56 -37
- package/dist/esm/descriptor-set.js +1 -1
- package/dist/esm/enum.js +1 -1
- package/dist/esm/extension-accessor.d.ts +35 -0
- package/dist/esm/extension-accessor.js +101 -0
- package/dist/esm/extension.d.ts +24 -0
- package/dist/esm/extension.js +14 -0
- package/dist/esm/field-list.js +1 -1
- package/dist/esm/field.js +1 -1
- package/dist/esm/google/protobuf/any_pb.js +1 -1
- package/dist/esm/google/protobuf/api_pb.js +1 -1
- package/dist/esm/google/protobuf/compiler/plugin_pb.js +1 -1
- package/dist/esm/google/protobuf/descriptor_pb.js +2 -2
- package/dist/esm/google/protobuf/duration_pb.js +1 -1
- package/dist/esm/google/protobuf/empty_pb.js +1 -1
- package/dist/esm/google/protobuf/field_mask_pb.js +1 -1
- package/dist/esm/google/protobuf/source_context_pb.js +1 -1
- package/dist/esm/google/protobuf/struct_pb.js +2 -2
- package/dist/esm/google/protobuf/timestamp_pb.js +1 -1
- package/dist/esm/google/protobuf/type_pb.js +2 -2
- 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/json-format.d.ts +5 -5
- package/dist/esm/json-format.js +1 -1
- package/dist/esm/message-type.js +1 -1
- package/dist/esm/message.js +1 -1
- package/dist/esm/private/assert.js +1 -1
- package/dist/esm/private/binary-format-common.d.ts +2 -3
- package/dist/esm/private/binary-format-common.js +80 -77
- package/dist/esm/private/binary-format-proto2.js +59 -64
- package/dist/esm/private/binary-format-proto3.js +44 -40
- package/dist/esm/private/enum.js +1 -1
- package/dist/esm/private/extensions.d.ts +34 -0
- package/dist/esm/private/extensions.js +81 -0
- package/dist/esm/private/feature-set.d.ts +6 -8
- package/dist/esm/private/feature-set.js +40 -41
- package/dist/esm/private/field-list.js +1 -1
- package/dist/esm/private/field-wrapper.d.ts +2 -2
- package/dist/esm/private/field-wrapper.js +1 -1
- package/dist/esm/private/field.js +1 -1
- package/dist/esm/private/json-format-common.d.ts +3 -3
- package/dist/esm/private/json-format-common.js +228 -173
- package/dist/esm/private/json-format-proto2.js +3 -2
- package/dist/esm/private/json-format-proto3.js +8 -6
- package/dist/esm/private/message-type.js +1 -1
- package/dist/esm/private/names.d.ts +2 -2
- package/dist/esm/private/names.js +3 -2
- package/dist/esm/private/options-map.js +1 -1
- package/dist/esm/private/proto-runtime.d.ts +6 -0
- package/dist/esm/private/proto-runtime.js +5 -1
- package/dist/esm/private/reify-wkt.js +1 -1
- package/dist/esm/private/scalars.js +1 -1
- package/dist/esm/private/text-format.js +1 -1
- package/dist/esm/private/util-common.js +1 -1
- package/dist/esm/private/util.js +1 -1
- package/dist/esm/proto-base64.js +1 -1
- package/dist/esm/proto-delimited.js +1 -1
- package/dist/esm/proto-double.js +1 -1
- package/dist/esm/proto-int64.js +1 -1
- package/dist/esm/proto2.js +1 -1
- package/dist/esm/proto3.js +1 -1
- package/dist/esm/service-type.js +1 -1
- package/dist/esm/to-plain-message.js +1 -1
- package/dist/esm/type-registry.d.ts +14 -0
- package/dist/esm/type-registry.js +1 -1
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
// Copyright 2021-
|
|
2
|
+
// Copyright 2021-2024 Buf Technologies, Inc.
|
|
3
3
|
//
|
|
4
4
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
5
|
// you may not use this file except in compliance with the License.
|
|
@@ -19,6 +19,8 @@ const field_js_1 = require("../field.js");
|
|
|
19
19
|
const assert_js_1 = require("./assert.js");
|
|
20
20
|
const proto_int64_js_1 = require("../proto-int64.js");
|
|
21
21
|
const proto_base64_js_1 = require("../proto-base64.js");
|
|
22
|
+
const extensions_js_1 = require("./extensions.js");
|
|
23
|
+
const extension_accessor_js_1 = require("../extension-accessor.js");
|
|
22
24
|
/* eslint-disable no-case-declarations, @typescript-eslint/restrict-plus-operands,@typescript-eslint/no-explicit-any,@typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-argument */
|
|
23
25
|
// Default options for parsing JSON.
|
|
24
26
|
const jsonReadDefaults = {
|
|
@@ -37,171 +39,52 @@ function makeReadOptions(options) {
|
|
|
37
39
|
function makeWriteOptions(options) {
|
|
38
40
|
return options ? Object.assign(Object.assign({}, jsonWriteDefaults), options) : jsonWriteDefaults;
|
|
39
41
|
}
|
|
40
|
-
function makeJsonFormatCommon(makeWriteField) {
|
|
42
|
+
function makeJsonFormatCommon(nullAsZeroValue, makeWriteField) {
|
|
41
43
|
const writeField = makeWriteField(writeEnum, writeScalar);
|
|
42
44
|
return {
|
|
43
45
|
makeReadOptions,
|
|
44
46
|
makeWriteOptions,
|
|
45
47
|
readMessage(type, json, options, message) {
|
|
46
48
|
if (json == null || Array.isArray(json) || typeof json != "object") {
|
|
47
|
-
throw new Error(`cannot decode message ${type.typeName} from JSON: ${
|
|
49
|
+
throw new Error(`cannot decode message ${type.typeName} from JSON: ${debugJsonValue(json)}`);
|
|
48
50
|
}
|
|
49
51
|
message = message !== null && message !== void 0 ? message : new type();
|
|
50
|
-
const oneofSeen =
|
|
52
|
+
const oneofSeen = new Map();
|
|
53
|
+
const registry = options.typeRegistry;
|
|
51
54
|
for (const [jsonKey, jsonValue] of Object.entries(json)) {
|
|
52
55
|
const field = type.fields.findJsonName(jsonKey);
|
|
53
|
-
if (
|
|
54
|
-
if (
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
}
|
|
59
|
-
let localName = field.localName;
|
|
60
|
-
let target = message;
|
|
61
|
-
if (field.oneof) {
|
|
62
|
-
if (jsonValue === null && field.kind == "scalar") {
|
|
63
|
-
// see conformance test Required.Proto3.JsonInput.OneofFieldNull{First,Second}
|
|
64
|
-
continue;
|
|
65
|
-
}
|
|
66
|
-
const seen = oneofSeen[field.oneof.localName];
|
|
67
|
-
if (seen) {
|
|
68
|
-
throw new Error(`cannot decode message ${type.typeName} from JSON: multiple keys for oneof "${field.oneof.name}" present: "${seen}", "${jsonKey}"`);
|
|
69
|
-
}
|
|
70
|
-
oneofSeen[field.oneof.localName] = jsonKey;
|
|
71
|
-
target = target[field.oneof.localName] = { case: localName };
|
|
72
|
-
localName = "value";
|
|
73
|
-
}
|
|
74
|
-
if (field.repeated) {
|
|
75
|
-
if (jsonValue === null) {
|
|
76
|
-
continue;
|
|
77
|
-
}
|
|
78
|
-
if (!Array.isArray(jsonValue)) {
|
|
79
|
-
throw new Error(`cannot decode field ${type.typeName}.${field.name} from JSON: ${this.debug(jsonValue)}`);
|
|
80
|
-
}
|
|
81
|
-
const targetArray = target[localName];
|
|
82
|
-
for (const jsonItem of jsonValue) {
|
|
83
|
-
if (jsonItem === null) {
|
|
84
|
-
throw new Error(`cannot decode field ${type.typeName}.${field.name} from JSON: ${this.debug(jsonItem)}`);
|
|
56
|
+
if (field) {
|
|
57
|
+
if (field.oneof) {
|
|
58
|
+
if (jsonValue === null && field.kind == "scalar") {
|
|
59
|
+
// see conformance test Required.Proto3.JsonInput.OneofFieldNull{First,Second}
|
|
60
|
+
continue;
|
|
85
61
|
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
case "message":
|
|
90
|
-
val = field.T.fromJson(jsonItem, options);
|
|
91
|
-
break;
|
|
92
|
-
case "enum":
|
|
93
|
-
val = readEnum(field.T, jsonItem, options.ignoreUnknownFields);
|
|
94
|
-
if (val === undefined)
|
|
95
|
-
continue;
|
|
96
|
-
break;
|
|
97
|
-
case "scalar":
|
|
98
|
-
try {
|
|
99
|
-
val = readScalar(field.T, jsonItem, field.L);
|
|
100
|
-
}
|
|
101
|
-
catch (e) {
|
|
102
|
-
let m = `cannot decode field ${type.typeName}.${field.name} from JSON: ${this.debug(jsonItem)}`;
|
|
103
|
-
if (e instanceof Error && e.message.length > 0) {
|
|
104
|
-
m += `: ${e.message}`;
|
|
105
|
-
}
|
|
106
|
-
throw new Error(m);
|
|
107
|
-
}
|
|
108
|
-
break;
|
|
62
|
+
const seen = oneofSeen.get(field.oneof);
|
|
63
|
+
if (seen !== undefined) {
|
|
64
|
+
throw new Error(`cannot decode message ${type.typeName} from JSON: multiple keys for oneof "${field.oneof.name}" present: "${seen}", "${jsonKey}"`);
|
|
109
65
|
}
|
|
110
|
-
|
|
66
|
+
oneofSeen.set(field.oneof, jsonKey);
|
|
111
67
|
}
|
|
68
|
+
readField(message, jsonValue, field, options, type, nullAsZeroValue);
|
|
112
69
|
}
|
|
113
|
-
else
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
case "message":
|
|
128
|
-
val = field.V.T.fromJson(jsonMapValue, options);
|
|
129
|
-
break;
|
|
130
|
-
case "enum":
|
|
131
|
-
val = readEnum(field.V.T, jsonMapValue, options.ignoreUnknownFields);
|
|
132
|
-
if (val === undefined)
|
|
133
|
-
continue;
|
|
134
|
-
break;
|
|
135
|
-
case "scalar":
|
|
136
|
-
try {
|
|
137
|
-
val = readScalar(field.V.T, jsonMapValue, field_js_1.LongType.BIGINT);
|
|
138
|
-
}
|
|
139
|
-
catch (e) {
|
|
140
|
-
let m = `cannot decode map value for field ${type.typeName}.${field.name} from JSON: ${this.debug(jsonValue)}`;
|
|
141
|
-
if (e instanceof Error && e.message.length > 0) {
|
|
142
|
-
m += `: ${e.message}`;
|
|
143
|
-
}
|
|
144
|
-
throw new Error(m);
|
|
145
|
-
}
|
|
146
|
-
break;
|
|
147
|
-
}
|
|
148
|
-
try {
|
|
149
|
-
targetMap[readScalar(field.K, field.K == field_js_1.ScalarType.BOOL
|
|
150
|
-
? jsonMapKey == "true"
|
|
151
|
-
? true
|
|
152
|
-
: jsonMapKey == "false"
|
|
153
|
-
? false
|
|
154
|
-
: jsonMapKey
|
|
155
|
-
: jsonMapKey, field_js_1.LongType.BIGINT).toString()] = val;
|
|
156
|
-
}
|
|
157
|
-
catch (e) {
|
|
158
|
-
let m = `cannot decode map key for field ${type.typeName}.${field.name} from JSON: ${this.debug(jsonValue)}`;
|
|
159
|
-
if (e instanceof Error && e.message.length > 0) {
|
|
160
|
-
m += `: ${e.message}`;
|
|
161
|
-
}
|
|
162
|
-
throw new Error(m);
|
|
70
|
+
else {
|
|
71
|
+
let found = false;
|
|
72
|
+
if ((registry === null || registry === void 0 ? void 0 : registry.findExtension) &&
|
|
73
|
+
jsonKey.startsWith("[") &&
|
|
74
|
+
jsonKey.endsWith("]")) {
|
|
75
|
+
const ext = registry.findExtension(jsonKey.substring(1, jsonKey.length - 1));
|
|
76
|
+
if (ext && ext.extendee.typeName == type.typeName) {
|
|
77
|
+
found = true;
|
|
78
|
+
const [container, get] = (0, extensions_js_1.createExtensionContainer)(ext);
|
|
79
|
+
readField(container, jsonValue, ext.field, options, ext, true);
|
|
80
|
+
// We pass on the options as BinaryReadOptions/BinaryWriteOptions,
|
|
81
|
+
// so that users can bring their own binary reader and writer factories
|
|
82
|
+
// if necessary.
|
|
83
|
+
(0, extension_accessor_js_1.setExtension)(message, ext, get(), options);
|
|
163
84
|
}
|
|
164
85
|
}
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
switch (field.kind) {
|
|
168
|
-
case "message":
|
|
169
|
-
const messageType = field.T;
|
|
170
|
-
if (jsonValue === null &&
|
|
171
|
-
messageType.typeName != "google.protobuf.Value") {
|
|
172
|
-
if (field.oneof) {
|
|
173
|
-
throw new Error(`cannot decode field ${type.typeName}.${field.name} from JSON: null is invalid for oneof field "${jsonKey}"`);
|
|
174
|
-
}
|
|
175
|
-
continue;
|
|
176
|
-
}
|
|
177
|
-
if (target[localName] instanceof message_js_1.Message) {
|
|
178
|
-
target[localName].fromJson(jsonValue, options);
|
|
179
|
-
}
|
|
180
|
-
else {
|
|
181
|
-
target[localName] = messageType.fromJson(jsonValue, options);
|
|
182
|
-
if (messageType.fieldWrapper && !field.oneof) {
|
|
183
|
-
target[localName] = messageType.fieldWrapper.unwrapField(target[localName]);
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
break;
|
|
187
|
-
case "enum":
|
|
188
|
-
const enumValue = readEnum(field.T, jsonValue, options.ignoreUnknownFields);
|
|
189
|
-
if (enumValue !== undefined) {
|
|
190
|
-
target[localName] = enumValue;
|
|
191
|
-
}
|
|
192
|
-
break;
|
|
193
|
-
case "scalar":
|
|
194
|
-
try {
|
|
195
|
-
target[localName] = readScalar(field.T, jsonValue, field.L);
|
|
196
|
-
}
|
|
197
|
-
catch (e) {
|
|
198
|
-
let m = `cannot decode field ${type.typeName}.${field.name} from JSON: ${this.debug(jsonValue)}`;
|
|
199
|
-
if (e instanceof Error && e.message.length > 0) {
|
|
200
|
-
m += `: ${e.message}`;
|
|
201
|
-
}
|
|
202
|
-
throw new Error(m);
|
|
203
|
-
}
|
|
204
|
-
break;
|
|
86
|
+
if (!found && !options.ignoreUnknownFields) {
|
|
87
|
+
throw new Error(`cannot decode message ${type.typeName} from JSON: key "${jsonKey}" is unknown`);
|
|
205
88
|
}
|
|
206
89
|
}
|
|
207
90
|
}
|
|
@@ -234,6 +117,21 @@ function makeJsonFormatCommon(makeWriteField) {
|
|
|
234
117
|
jsonValue;
|
|
235
118
|
}
|
|
236
119
|
}
|
|
120
|
+
const registry = options.typeRegistry;
|
|
121
|
+
if (registry === null || registry === void 0 ? void 0 : registry.findExtensionFor) {
|
|
122
|
+
for (const uf of type.runtime.bin.listUnknownFields(message)) {
|
|
123
|
+
const ext = registry.findExtensionFor(type.typeName, uf.no);
|
|
124
|
+
if (ext && (0, extension_accessor_js_1.hasExtension)(message, ext)) {
|
|
125
|
+
// We pass on the options as BinaryReadOptions, so that users can bring their own
|
|
126
|
+
// binary reader factory if necessary.
|
|
127
|
+
const value = (0, extension_accessor_js_1.getExtension)(message, ext, options);
|
|
128
|
+
const jsonValue = writeField(ext.field, value, options);
|
|
129
|
+
if (jsonValue !== undefined) {
|
|
130
|
+
json[ext.field.jsonName] = jsonValue;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
237
135
|
}
|
|
238
136
|
catch (e) {
|
|
239
137
|
const m = field
|
|
@@ -244,7 +142,7 @@ function makeJsonFormatCommon(makeWriteField) {
|
|
|
244
142
|
}
|
|
245
143
|
return json;
|
|
246
144
|
},
|
|
247
|
-
readScalar,
|
|
145
|
+
readScalar: (type, json, longType) => readScalar(type, json, longType, nullAsZeroValue), // eslint-disable-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-return
|
|
248
146
|
writeScalar,
|
|
249
147
|
debug: debugJsonValue,
|
|
250
148
|
};
|
|
@@ -263,9 +161,162 @@ function debugJsonValue(json) {
|
|
|
263
161
|
return String(json);
|
|
264
162
|
}
|
|
265
163
|
}
|
|
164
|
+
// Read a JSON value for a field.
|
|
165
|
+
// The "type" argument is only used to provide context in errors.
|
|
166
|
+
// The argument "nullAsZeroValue" applies to singular fields (not repeated, map,
|
|
167
|
+
// or oneof). If the argument is `true`, JSON null is parsed as the fields
|
|
168
|
+
// zero-value. If the argument is false, JSON null sets the field to `undefined`.
|
|
169
|
+
function readField(target, // eslint-disable-line @typescript-eslint/no-explicit-any -- `any` is the best choice for dynamic access
|
|
170
|
+
jsonValue, field, options, type, nullAsZeroValue) {
|
|
171
|
+
let localName = field.localName;
|
|
172
|
+
if (field.oneof) {
|
|
173
|
+
if (jsonValue === null && field.kind == "scalar") {
|
|
174
|
+
// see conformance test Required.Proto3.JsonInput.OneofFieldNull{First,Second}
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
target = target[field.oneof.localName] = { case: localName };
|
|
178
|
+
localName = "value";
|
|
179
|
+
}
|
|
180
|
+
if (field.repeated) {
|
|
181
|
+
if (jsonValue === null) {
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
if (!Array.isArray(jsonValue)) {
|
|
185
|
+
throw new Error(`cannot decode field ${type.typeName}.${field.name} from JSON: ${debugJsonValue(jsonValue)}`);
|
|
186
|
+
}
|
|
187
|
+
const targetArray = target[localName];
|
|
188
|
+
for (const jsonItem of jsonValue) {
|
|
189
|
+
if (jsonItem === null) {
|
|
190
|
+
throw new Error(`cannot decode field ${type.typeName}.${field.name} from JSON: ${debugJsonValue(jsonItem)}`);
|
|
191
|
+
}
|
|
192
|
+
let val;
|
|
193
|
+
// eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check -- "map" is invalid for repeated fields
|
|
194
|
+
switch (field.kind) {
|
|
195
|
+
case "message":
|
|
196
|
+
val = field.T.fromJson(jsonItem, options);
|
|
197
|
+
break;
|
|
198
|
+
case "enum":
|
|
199
|
+
val = readEnum(field.T, jsonItem, options.ignoreUnknownFields, true);
|
|
200
|
+
if (val === undefined)
|
|
201
|
+
continue;
|
|
202
|
+
break;
|
|
203
|
+
case "scalar":
|
|
204
|
+
try {
|
|
205
|
+
val = readScalar(field.T, jsonItem, field.L, true);
|
|
206
|
+
}
|
|
207
|
+
catch (e) {
|
|
208
|
+
let m = `cannot decode field ${type.typeName}.${field.name} from JSON: ${debugJsonValue(jsonItem)}`;
|
|
209
|
+
if (e instanceof Error && e.message.length > 0) {
|
|
210
|
+
m += `: ${e.message}`;
|
|
211
|
+
}
|
|
212
|
+
throw new Error(m);
|
|
213
|
+
}
|
|
214
|
+
break;
|
|
215
|
+
}
|
|
216
|
+
targetArray.push(val);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
else if (field.kind == "map") {
|
|
220
|
+
if (jsonValue === null) {
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
if (typeof jsonValue != "object" || Array.isArray(jsonValue)) {
|
|
224
|
+
throw new Error(`cannot decode field ${type.typeName}.${field.name} from JSON: ${debugJsonValue(jsonValue)}`);
|
|
225
|
+
}
|
|
226
|
+
const targetMap = target[localName];
|
|
227
|
+
for (const [jsonMapKey, jsonMapValue] of Object.entries(jsonValue)) {
|
|
228
|
+
if (jsonMapValue === null) {
|
|
229
|
+
throw new Error(`cannot decode field ${type.typeName}.${field.name} from JSON: map value null`);
|
|
230
|
+
}
|
|
231
|
+
let val;
|
|
232
|
+
switch (field.V.kind) {
|
|
233
|
+
case "message":
|
|
234
|
+
val = field.V.T.fromJson(jsonMapValue, options);
|
|
235
|
+
break;
|
|
236
|
+
case "enum":
|
|
237
|
+
val = readEnum(field.V.T, jsonMapValue, options.ignoreUnknownFields, true);
|
|
238
|
+
if (val === undefined)
|
|
239
|
+
continue;
|
|
240
|
+
break;
|
|
241
|
+
case "scalar":
|
|
242
|
+
try {
|
|
243
|
+
val = readScalar(field.V.T, jsonMapValue, field_js_1.LongType.BIGINT, true);
|
|
244
|
+
}
|
|
245
|
+
catch (e) {
|
|
246
|
+
let m = `cannot decode map value for field ${type.typeName}.${field.name} from JSON: ${debugJsonValue(jsonValue)}`;
|
|
247
|
+
if (e instanceof Error && e.message.length > 0) {
|
|
248
|
+
m += `: ${e.message}`;
|
|
249
|
+
}
|
|
250
|
+
throw new Error(m);
|
|
251
|
+
}
|
|
252
|
+
break;
|
|
253
|
+
}
|
|
254
|
+
try {
|
|
255
|
+
targetMap[readScalar(field.K, field.K == field_js_1.ScalarType.BOOL
|
|
256
|
+
? jsonMapKey == "true"
|
|
257
|
+
? true
|
|
258
|
+
: jsonMapKey == "false"
|
|
259
|
+
? false
|
|
260
|
+
: jsonMapKey
|
|
261
|
+
: jsonMapKey, field_js_1.LongType.BIGINT, true).toString()] = val;
|
|
262
|
+
}
|
|
263
|
+
catch (e) {
|
|
264
|
+
let m = `cannot decode map key for field ${type.typeName}.${field.name} from JSON: ${debugJsonValue(jsonValue)}`;
|
|
265
|
+
if (e instanceof Error && e.message.length > 0) {
|
|
266
|
+
m += `: ${e.message}`;
|
|
267
|
+
}
|
|
268
|
+
throw new Error(m);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
else {
|
|
273
|
+
switch (field.kind) {
|
|
274
|
+
case "message":
|
|
275
|
+
const messageType = field.T;
|
|
276
|
+
if (jsonValue === null &&
|
|
277
|
+
messageType.typeName != "google.protobuf.Value") {
|
|
278
|
+
if (field.oneof) {
|
|
279
|
+
throw new Error(`cannot decode field ${type.typeName}.${field.name} from JSON: null is invalid for oneof field`);
|
|
280
|
+
}
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
if (target[localName] instanceof message_js_1.Message) {
|
|
284
|
+
target[localName].fromJson(jsonValue, options);
|
|
285
|
+
}
|
|
286
|
+
else {
|
|
287
|
+
target[localName] = messageType.fromJson(jsonValue, options);
|
|
288
|
+
if (messageType.fieldWrapper && !field.oneof) {
|
|
289
|
+
target[localName] = messageType.fieldWrapper.unwrapField(target[localName]);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
break;
|
|
293
|
+
case "enum":
|
|
294
|
+
const enumValue = readEnum(field.T, jsonValue, options.ignoreUnknownFields, nullAsZeroValue);
|
|
295
|
+
if (enumValue !== undefined) {
|
|
296
|
+
target[localName] = enumValue;
|
|
297
|
+
}
|
|
298
|
+
break;
|
|
299
|
+
case "scalar":
|
|
300
|
+
try {
|
|
301
|
+
target[localName] = readScalar(field.T, jsonValue, field.L, nullAsZeroValue);
|
|
302
|
+
}
|
|
303
|
+
catch (e) {
|
|
304
|
+
let m = `cannot decode field ${type.typeName}.${field.name} from JSON: ${debugJsonValue(jsonValue)}`;
|
|
305
|
+
if (e instanceof Error && e.message.length > 0) {
|
|
306
|
+
m += `: ${e.message}`;
|
|
307
|
+
}
|
|
308
|
+
throw new Error(m);
|
|
309
|
+
}
|
|
310
|
+
break;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
}
|
|
266
314
|
// May throw an error. If the error message is non-blank, it should be shown.
|
|
267
315
|
// It is up to the caller to provide context.
|
|
268
|
-
function
|
|
316
|
+
// If the argument "nullAsZeroValue" is `true`, this function returns the zero-value
|
|
317
|
+
// for JSON null. If the argument is `false`, this function returns `undefined`
|
|
318
|
+
// for JSON null.
|
|
319
|
+
function readScalar(type, json, longType, nullAsZeroValue) {
|
|
269
320
|
// every valid case in the switch below returns, and every fall
|
|
270
321
|
// through is regarded as a failure.
|
|
271
322
|
switch (type) {
|
|
@@ -274,7 +325,7 @@ function readScalar(type, json, longType) {
|
|
|
274
325
|
case field_js_1.ScalarType.DOUBLE:
|
|
275
326
|
case field_js_1.ScalarType.FLOAT:
|
|
276
327
|
if (json === null)
|
|
277
|
-
return 0.0;
|
|
328
|
+
return nullAsZeroValue ? 0.0 : undefined;
|
|
278
329
|
if (json === "NaN")
|
|
279
330
|
return Number.NaN;
|
|
280
331
|
if (json === "Infinity")
|
|
@@ -311,7 +362,7 @@ function readScalar(type, json, longType) {
|
|
|
311
362
|
case field_js_1.ScalarType.SINT32:
|
|
312
363
|
case field_js_1.ScalarType.UINT32:
|
|
313
364
|
if (json === null)
|
|
314
|
-
return 0;
|
|
365
|
+
return nullAsZeroValue ? 0 : undefined;
|
|
315
366
|
let int32;
|
|
316
367
|
if (typeof json == "number")
|
|
317
368
|
int32 = json;
|
|
@@ -331,7 +382,7 @@ function readScalar(type, json, longType) {
|
|
|
331
382
|
case field_js_1.ScalarType.SFIXED64:
|
|
332
383
|
case field_js_1.ScalarType.SINT64:
|
|
333
384
|
if (json === null)
|
|
334
|
-
return proto_int64_js_1.protoInt64.zero;
|
|
385
|
+
return nullAsZeroValue ? proto_int64_js_1.protoInt64.zero : undefined;
|
|
335
386
|
if (typeof json != "number" && typeof json != "string")
|
|
336
387
|
break;
|
|
337
388
|
const long = proto_int64_js_1.protoInt64.parse(json);
|
|
@@ -340,7 +391,7 @@ function readScalar(type, json, longType) {
|
|
|
340
391
|
case field_js_1.ScalarType.FIXED64:
|
|
341
392
|
case field_js_1.ScalarType.UINT64:
|
|
342
393
|
if (json === null)
|
|
343
|
-
return proto_int64_js_1.protoInt64.zero;
|
|
394
|
+
return nullAsZeroValue ? proto_int64_js_1.protoInt64.zero : undefined;
|
|
344
395
|
if (typeof json != "number" && typeof json != "string")
|
|
345
396
|
break;
|
|
346
397
|
const uLong = proto_int64_js_1.protoInt64.uParse(json);
|
|
@@ -349,14 +400,14 @@ function readScalar(type, json, longType) {
|
|
|
349
400
|
// bool:
|
|
350
401
|
case field_js_1.ScalarType.BOOL:
|
|
351
402
|
if (json === null)
|
|
352
|
-
return false;
|
|
403
|
+
return nullAsZeroValue ? false : undefined;
|
|
353
404
|
if (typeof json !== "boolean")
|
|
354
405
|
break;
|
|
355
406
|
return json;
|
|
356
407
|
// string:
|
|
357
408
|
case field_js_1.ScalarType.STRING:
|
|
358
409
|
if (json === null)
|
|
359
|
-
return "";
|
|
410
|
+
return nullAsZeroValue ? "" : undefined;
|
|
360
411
|
if (typeof json !== "string") {
|
|
361
412
|
break;
|
|
362
413
|
}
|
|
@@ -372,7 +423,9 @@ function readScalar(type, json, longType) {
|
|
|
372
423
|
// bytes: JSON value will be the data encoded as a string using standard base64 encoding with paddings.
|
|
373
424
|
// Either standard or URL-safe base64 encoding with/without paddings are accepted.
|
|
374
425
|
case field_js_1.ScalarType.BYTES:
|
|
375
|
-
if (json === null
|
|
426
|
+
if (json === null)
|
|
427
|
+
return nullAsZeroValue ? new Uint8Array(0) : undefined;
|
|
428
|
+
if (json === "")
|
|
376
429
|
return new Uint8Array(0);
|
|
377
430
|
if (typeof json !== "string")
|
|
378
431
|
break;
|
|
@@ -380,10 +433,14 @@ function readScalar(type, json, longType) {
|
|
|
380
433
|
}
|
|
381
434
|
throw new Error();
|
|
382
435
|
}
|
|
383
|
-
function
|
|
436
|
+
// If the argument "nullAsZeroValue" is `true`, this function returns the first
|
|
437
|
+
// enum value for JSON null. If the argument is `false`, this function returns
|
|
438
|
+
// `undefined`.
|
|
439
|
+
function readEnum(type, json, ignoreUnknownFields, nullAsZeroValue) {
|
|
384
440
|
if (json === null) {
|
|
385
|
-
// proto3 requires 0 to be default value for all enums
|
|
386
|
-
|
|
441
|
+
// proto3 requires 0 to be default value for all enums (which is required to be the first value).
|
|
442
|
+
// proto2 uses the first value (at least with protoc-gen-go).
|
|
443
|
+
return nullAsZeroValue ? type.values[0].no : undefined;
|
|
387
444
|
}
|
|
388
445
|
// eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check
|
|
389
446
|
switch (typeof json) {
|
|
@@ -402,12 +459,12 @@ function readEnum(type, json, ignoreUnknownFields) {
|
|
|
402
459
|
}
|
|
403
460
|
throw new Error(`cannot decode enum ${type.typeName} from JSON: ${debugJsonValue(json)}`);
|
|
404
461
|
}
|
|
405
|
-
function writeEnum(type, value,
|
|
462
|
+
function writeEnum(type, value, emitZeroValue, enumAsInteger) {
|
|
406
463
|
var _a;
|
|
407
464
|
if (value === undefined) {
|
|
408
465
|
return value;
|
|
409
466
|
}
|
|
410
|
-
if (
|
|
467
|
+
if (!emitZeroValue && type.values[0].no === value) {
|
|
411
468
|
// proto3 requires 0 to be default value for all enums
|
|
412
469
|
return undefined;
|
|
413
470
|
}
|
|
@@ -420,7 +477,7 @@ function writeEnum(type, value, emitIntrinsicDefault, enumAsInteger) {
|
|
|
420
477
|
const val = type.findNumber(value);
|
|
421
478
|
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
|
|
422
479
|
}
|
|
423
|
-
function writeScalar(type, value,
|
|
480
|
+
function writeScalar(type, value, emitZeroValue) {
|
|
424
481
|
if (value === undefined) {
|
|
425
482
|
return undefined;
|
|
426
483
|
}
|
|
@@ -432,7 +489,7 @@ function writeScalar(type, value, emitIntrinsicDefault) {
|
|
|
432
489
|
case field_js_1.ScalarType.FIXED32:
|
|
433
490
|
case field_js_1.ScalarType.UINT32:
|
|
434
491
|
(0, assert_js_1.assert)(typeof value == "number");
|
|
435
|
-
return value != 0 ||
|
|
492
|
+
return value != 0 || emitZeroValue ? value : undefined;
|
|
436
493
|
// float, double: JSON value will be a number or one of the special string values "NaN", "Infinity", and "-Infinity".
|
|
437
494
|
// Either numbers or strings are accepted. Exponent notation is also accepted.
|
|
438
495
|
case field_js_1.ScalarType.FLOAT:
|
|
@@ -445,15 +502,15 @@ function writeScalar(type, value, emitIntrinsicDefault) {
|
|
|
445
502
|
return "Infinity";
|
|
446
503
|
if (value === Number.NEGATIVE_INFINITY)
|
|
447
504
|
return "-Infinity";
|
|
448
|
-
return value !== 0 ||
|
|
505
|
+
return value !== 0 || emitZeroValue ? value : undefined;
|
|
449
506
|
// string:
|
|
450
507
|
case field_js_1.ScalarType.STRING:
|
|
451
508
|
(0, assert_js_1.assert)(typeof value == "string");
|
|
452
|
-
return value.length > 0 ||
|
|
509
|
+
return value.length > 0 || emitZeroValue ? value : undefined;
|
|
453
510
|
// bool:
|
|
454
511
|
case field_js_1.ScalarType.BOOL:
|
|
455
512
|
(0, assert_js_1.assert)(typeof value == "boolean");
|
|
456
|
-
return value ||
|
|
513
|
+
return value || emitZeroValue ? value : undefined;
|
|
457
514
|
// JSON value will be a decimal string. Either numbers or strings are accepted.
|
|
458
515
|
case field_js_1.ScalarType.UINT64:
|
|
459
516
|
case field_js_1.ScalarType.FIXED64:
|
|
@@ -466,14 +523,12 @@ function writeScalar(type, value, emitIntrinsicDefault) {
|
|
|
466
523
|
// We use implicit conversion with `value != 0` to catch both 0n and "0"
|
|
467
524
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
468
525
|
// @ts-ignore
|
|
469
|
-
return
|
|
470
|
-
? value.toString(10)
|
|
471
|
-
: undefined;
|
|
526
|
+
return emitZeroValue || value != 0 ? value.toString(10) : undefined;
|
|
472
527
|
// bytes: JSON value will be the data encoded as a string using standard base64 encoding with paddings.
|
|
473
528
|
// Either standard or URL-safe base64 encoding with/without paddings are accepted.
|
|
474
529
|
case field_js_1.ScalarType.BYTES:
|
|
475
530
|
(0, assert_js_1.assert)(value instanceof Uint8Array);
|
|
476
|
-
return
|
|
531
|
+
return emitZeroValue || value.byteLength > 0
|
|
477
532
|
? proto_base64_js_1.protoBase64.enc(value)
|
|
478
533
|
: undefined;
|
|
479
534
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
// Copyright 2021-
|
|
2
|
+
// Copyright 2021-2024 Buf Technologies, Inc.
|
|
3
3
|
//
|
|
4
4
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
5
|
// you may not use this file except in compliance with the License.
|
|
@@ -19,7 +19,8 @@ const assert_js_1 = require("./assert.js");
|
|
|
19
19
|
const json_format_common_js_1 = require("./json-format-common.js");
|
|
20
20
|
/* eslint-disable no-case-declarations, @typescript-eslint/restrict-plus-operands,@typescript-eslint/no-explicit-any,@typescript-eslint/no-unsafe-return,@typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-argument */
|
|
21
21
|
function makeJsonFormatProto2() {
|
|
22
|
-
|
|
22
|
+
// TODO field presence: merge this function with proto3. the reading side already switches behavior on the nullAsZeroValue argument.
|
|
23
|
+
return (0, json_format_common_js_1.makeJsonFormatCommon)(false, (writeEnum, writeScalar) => {
|
|
23
24
|
return function writeField(field, value, options) {
|
|
24
25
|
if (field.kind == "map") {
|
|
25
26
|
const jsonObj = {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
// Copyright 2021-
|
|
2
|
+
// Copyright 2021-2024 Buf Technologies, Inc.
|
|
3
3
|
//
|
|
4
4
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
5
|
// you may not use this file except in compliance with the License.
|
|
@@ -19,7 +19,8 @@ const assert_js_1 = require("./assert.js");
|
|
|
19
19
|
const json_format_common_js_1 = require("./json-format-common.js");
|
|
20
20
|
/* eslint-disable no-case-declarations, @typescript-eslint/restrict-plus-operands,@typescript-eslint/no-explicit-any,@typescript-eslint/no-unsafe-return,@typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-argument */
|
|
21
21
|
function makeJsonFormatProto3() {
|
|
22
|
-
|
|
22
|
+
// TODO field presence: merge this function with proto2. the reading side already switches behavior on the nullAsZeroValue argument.
|
|
23
|
+
return (0, json_format_common_js_1.makeJsonFormatCommon)(true, (writeEnum, writeScalar) => {
|
|
23
24
|
return function writeField(field, value, options) {
|
|
24
25
|
if (field.kind == "map") {
|
|
25
26
|
const jsonObj = {};
|
|
@@ -66,7 +67,7 @@ function makeJsonFormatProto3() {
|
|
|
66
67
|
break;
|
|
67
68
|
case "message":
|
|
68
69
|
for (let i = 0; i < value.length; i++) {
|
|
69
|
-
jsonArr.push(
|
|
70
|
+
jsonArr.push(value[i].toJson(options));
|
|
70
71
|
}
|
|
71
72
|
break;
|
|
72
73
|
}
|
|
@@ -75,15 +76,16 @@ function makeJsonFormatProto3() {
|
|
|
75
76
|
: undefined;
|
|
76
77
|
}
|
|
77
78
|
else {
|
|
79
|
+
if (value === undefined) {
|
|
80
|
+
return undefined;
|
|
81
|
+
}
|
|
78
82
|
switch (field.kind) {
|
|
79
83
|
case "scalar":
|
|
80
84
|
return writeScalar(field.T, value, !!field.oneof || field.opt || options.emitDefaultValues);
|
|
81
85
|
case "enum":
|
|
82
86
|
return writeEnum(field.T, value, !!field.oneof || field.opt || options.emitDefaultValues, options.enumAsInteger);
|
|
83
87
|
case "message":
|
|
84
|
-
return
|
|
85
|
-
? (0, field_wrapper_js_1.wrapField)(field.T, value).toJson(options)
|
|
86
|
-
: undefined;
|
|
88
|
+
return (0, field_wrapper_js_1.wrapField)(field.T, value).toJson(options);
|
|
87
89
|
}
|
|
88
90
|
}
|
|
89
91
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { DescEnum, DescEnumValue, DescField, DescMessage, DescService } from "../descriptor-set.js";
|
|
1
|
+
import type { DescEnum, DescEnumValue, DescExtension, DescField, DescMessage, DescService } from "../descriptor-set.js";
|
|
2
2
|
import type { DescMethod, DescOneof } from "../descriptor-set.js";
|
|
3
3
|
/**
|
|
4
4
|
* Returns the name of a protobuf element in generated code.
|
|
@@ -8,7 +8,7 @@ import type { DescMethod, DescOneof } from "../descriptor-set.js";
|
|
|
8
8
|
* the type name. For nested messages and enumerations, the names are joined
|
|
9
9
|
* with an underscore. For methods, the first character is made lowercase.
|
|
10
10
|
*/
|
|
11
|
-
export declare function localName(desc: DescEnum | DescEnumValue | DescMessage | DescOneof | DescField | DescService | DescMethod): string;
|
|
11
|
+
export declare function localName(desc: DescEnum | DescEnumValue | DescMessage | DescExtension | DescOneof | DescField | DescService | DescMethod): string;
|
|
12
12
|
/**
|
|
13
13
|
* Returns the name of a field in generated code.
|
|
14
14
|
*/
|