in tfx_bsl/cc/coders/example_decoder.cc [594:649]
absl::Status DecodeTopLevelFeatures(
const google::protobuf::Map<std::string, tensorflow::Feature>& features,
absl::flat_hash_set<std::string>& all_features_seen,
const int num_examples_already_processed,
absl::flat_hash_map<std::string, std::unique_ptr<FeatureDecoder>>&
feature_decoders) {
for (const auto& p : features) {
const std::string& feature_name = p.first;
const tensorflow::Feature& feature = p.second;
const auto it = feature_decoders.find(feature_name);
FeatureDecoder* feature_decoder = nullptr;
if (it != feature_decoders.end()) {
feature_decoder = it->second.get();
} else {
all_features_seen.insert(feature_name);
switch (feature.kind_case()) {
case tensorflow::Feature::kInt64List:
feature_decoder = IntDecoder::Make();
break;
case tensorflow::Feature::kFloatList:
feature_decoder = FloatDecoder::Make();
break;
case tensorflow::Feature::kBytesList:
feature_decoder = BytesDecoder::Make();
break;
case tensorflow::Feature::KIND_NOT_SET:
// Leave feature_decoder as nullptr.
break;
}
if (feature_decoder) {
// Handle the situation in which we see a feature for the first time
// after already having processed some examples. In that case, append
// a null for each example that has already been processed (in which
// this feature was not seen), excluding the current example.
for (int j = 0; j < num_examples_already_processed; ++j) {
TFX_BSL_RETURN_IF_ERROR(feature_decoder->AppendNull());
}
feature_decoders[feature_name] = absl::WrapUnique(feature_decoder);
}
}
if (feature_decoder) {
absl::Status status = feature_decoder->DecodeFeature(feature);
if (!status.ok()) {
return absl::Status(status.code(),
absl::StrCat(status.message(), " for feature \"",
feature_name, "\""));
}
}
}
for (const auto& p : feature_decoders) {
TFX_BSL_RETURN_IF_ERROR(p.second->FinishFeature());
}
return absl::OkStatus();
}