mirror of
https://github.com/github/codeql-action.git
synced 2025-12-30 19:20:08 +08:00
Co-authored-by: Andrew Eisenberg <aeisenberg@github.com> Co-authored-by: Henry Mercer <henrymercer@github.com>
91 lines
4.0 KiB
JavaScript
91 lines
4.0 KiB
JavaScript
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.reflectionMergePartial = void 0;
|
|
/**
|
|
* Copy partial data into the target message.
|
|
*
|
|
* If a singular scalar or enum field is present in the source, it
|
|
* replaces the field in the target.
|
|
*
|
|
* If a singular message field is present in the source, it is merged
|
|
* with the target field by calling mergePartial() of the responsible
|
|
* message type.
|
|
*
|
|
* If a repeated field is present in the source, its values replace
|
|
* all values in the target array, removing extraneous values.
|
|
* Repeated message fields are copied, not merged.
|
|
*
|
|
* If a map field is present in the source, entries are added to the
|
|
* target map, replacing entries with the same key. Entries that only
|
|
* exist in the target remain. Entries with message values are copied,
|
|
* not merged.
|
|
*
|
|
* Note that this function differs from protobuf merge semantics,
|
|
* which appends repeated fields.
|
|
*/
|
|
function reflectionMergePartial(info, target, source) {
|
|
let fieldValue, // the field value we are working with
|
|
input = source, output; // where we want our field value to go
|
|
for (let field of info.fields) {
|
|
let name = field.localName;
|
|
if (field.oneof) {
|
|
const group = input[field.oneof]; // this is the oneof`s group in the source
|
|
if ((group === null || group === void 0 ? void 0 : group.oneofKind) == undefined) { // the user is free to omit
|
|
continue; // we skip this field, and all other members too
|
|
}
|
|
fieldValue = group[name]; // our value comes from the the oneof group of the source
|
|
output = target[field.oneof]; // and our output is the oneof group of the target
|
|
output.oneofKind = group.oneofKind; // always update discriminator
|
|
if (fieldValue == undefined) {
|
|
delete output[name]; // remove any existing value
|
|
continue; // skip further work on field
|
|
}
|
|
}
|
|
else {
|
|
fieldValue = input[name]; // we are using the source directly
|
|
output = target; // we want our field value to go directly into the target
|
|
if (fieldValue == undefined) {
|
|
continue; // skip further work on field, existing value is used as is
|
|
}
|
|
}
|
|
if (field.repeat)
|
|
output[name].length = fieldValue.length; // resize target array to match source array
|
|
// now we just work with `fieldValue` and `output` to merge the value
|
|
switch (field.kind) {
|
|
case "scalar":
|
|
case "enum":
|
|
if (field.repeat)
|
|
for (let i = 0; i < fieldValue.length; i++)
|
|
output[name][i] = fieldValue[i]; // not a reference type
|
|
else
|
|
output[name] = fieldValue; // not a reference type
|
|
break;
|
|
case "message":
|
|
let T = field.T();
|
|
if (field.repeat)
|
|
for (let i = 0; i < fieldValue.length; i++)
|
|
output[name][i] = T.create(fieldValue[i]);
|
|
else if (output[name] === undefined)
|
|
output[name] = T.create(fieldValue); // nothing to merge with
|
|
else
|
|
T.mergePartial(output[name], fieldValue);
|
|
break;
|
|
case "map":
|
|
// Map and repeated fields are simply overwritten, not appended or merged
|
|
switch (field.V.kind) {
|
|
case "scalar":
|
|
case "enum":
|
|
Object.assign(output[name], fieldValue); // elements are not reference types
|
|
break;
|
|
case "message":
|
|
let T = field.V.T();
|
|
for (let k of Object.keys(fieldValue))
|
|
output[name][k] = T.create(fieldValue[k]);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
exports.reflectionMergePartial = reflectionMergePartial;
|