glean/rts/define.cpp (70 lines of code) (raw):
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree.
*/
#include "glean/rts/define.h"
#include <folly/container/F14Map.h>
#include <folly/MapUtil.h>
namespace facebook {
namespace glean {
namespace rts {
/// Define all new facts in a Batch. The substition is used and updated
/// with the new facts. The facts are typechecked based on the inventory.
Substitution defineUntrustedBatch(
Define& def,
const Inventory& inventory,
Id first,
const Id * FOLLY_NULLABLE ids, // nullptr if there are no named facts
size_t count,
folly::ByteRange batch) {
if (first < Id::lowest()) {
error("invalid base id {} in batch", first);
}
Substitution subst(first, count);
folly::F14FastMap<Id,Id,folly::Hash> idmap;
binary::Input input(batch);
Id max_ref;
Renamer renamer([&](Id id, Pid type) {
const auto real_id = subst.subst(folly::get_default(idmap, id, id));
auto real_type = def.typeById(real_id);
if (real_type == type) {
if (real_id > max_ref) {
max_ref = real_id;
}
return real_id;
} else if (!real_type) {
error("invalid fact {}", id);
} else {
auto pred = inventory.lookupPredicate(type);
CHECK_NOTNULL(pred);
auto real_pred = inventory.lookupPredicate(real_type);
CHECK_NOTNULL(real_pred);
error("invalid reference to fact {}: expected {}.{}, got {}.{}",
id,
pred->name,
pred->version,
real_pred->name,
real_pred->version);
}
});
for (size_t i = 0; i < count; ++i) {
Pid ty;
Fact::Clause clause;
Fact::deserialize(input, ty, clause);
if (const auto *predicate = inventory.lookupPredicate(ty)) {
max_ref = Id::invalid();
binary::Output out;
uint64_t key_size;
predicate->typecheck(renamer, clause, out, key_size);
const auto id =
def.define(ty, Fact::Clause::from(out.bytes(), key_size), max_ref);
if (!id) {
error("invalid fact redefinition ({})", predicate->name);
}
subst.setAt(i, id);
if (ids && ids[i]) {
idmap[ids[i]] = id;
}
} else {
error("invalid predicate id {}", ty);
}
}
return subst;
}
}
}
}