/* * Copyright (c) Meta Platforms, Inc. and affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include template constexpr bool always_false_v = false; namespace oi::exporters { namespace { uint64_t parseVarint(std::vector::const_iterator& it); } ParsedData ParsedData::parse(std::vector::const_iterator& it, types::dy::Dynamic dy) { return std::visit( [&it](const auto el) -> ParsedData { auto ty = el.get(); using T = std::decay_t; if constexpr (std::is_same_v) { return ParsedData::Unit{}; } else if constexpr (std::is_same_v) { return ParsedData::VarInt{.value = parseVarint(it)}; } else if constexpr (std::is_same_v) { return ParsedData::Pair{ .first = Lazy{it, ty.first}, .second = Lazy{it, ty.second}, }; } else if constexpr (std::is_same_v) { return ParsedData::List{ .length = parseVarint(it), .values = {it, ty.element}, }; } else if constexpr (std::is_same_v) { auto index = parseVarint(it); assert(index < ty.variants.size()); return ParsedData::Sum{ .index = index, .value = {it, ty.variants[index]}, }; } else { static_assert(always_false_v, "non-exhaustive visitor!"); } }, dy); } namespace { uint64_t parseVarint(std::vector::const_iterator& it) { uint64_t v = 0; int shift = 0; while (*it >= 0x80) { v |= static_cast(*it++ & 0x7f) << shift; shift += 7; } v |= static_cast(*it++ & 0x7f) << shift; return v; } } // namespace } // namespace oi::exporters