123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115 |
- #pragma once
- #include "config.h"
- #include "proto2json_printer.h"
- #include "json_output_create.h"
- #include <library/cpp/protobuf/util/simple_reflection.h>
- #include <util/generic/maybe.h>
- #include <util/generic/yexception.h>
- #include <util/generic/utility.h>
- #include <functional>
- namespace NProtobufJson {
- template <typename TBasePrinter = TProto2JsonPrinter>
- class TInliningPrinter: public TBasePrinter {
- public:
- using TFieldPredicate = std::function<bool(const NProtoBuf::Message&,
- const NProtoBuf::FieldDescriptor*)>;
- template <typename... TArgs>
- TInliningPrinter(TFieldPredicate isInlined, TArgs&&... args)
- : TBasePrinter(std::forward<TArgs>(args)...)
- , IsInlined(std::move(isInlined))
- {
- }
- virtual void PrintField(const NProtoBuf::Message& proto,
- const NProtoBuf::FieldDescriptor& field,
- IJsonOutput& json,
- TStringBuf key) override {
- const NProtoBuf::TConstField f(proto, &field);
- if (!key && IsInlined(proto, &field) && ShouldPrint(f)) {
- key = this->MakeKey(field);
- json.WriteKey(key);
- if (!field.is_repeated()) {
- json.WriteRawJson(f.Get<TString>());
- } else {
- json.BeginList();
- for (size_t i = 0, sz = f.Size(); i < sz; ++i)
- json.WriteRawJson(f.Get<TString>(i));
- json.EndList();
- }
- } else {
- TBasePrinter::PrintField(proto, field, json, key);
- }
- }
- private:
- bool ShouldPrint(const NProtoBuf::TConstField& f) const {
- if (!f.IsString())
- ythrow yexception() << "TInliningPrinter: json field "
- << f.Field()->name() << " should be a string";
- if (f.HasValue())
- return true;
- // we may want write default value for given field in case of its absence
- const auto& cfg = this->GetConfig();
- return (f.Field()->is_repeated() ? cfg.MissingRepeatedKeyMode : cfg.MissingSingleKeyMode) == TProto2JsonConfig::MissingKeyDefault;
- }
- private:
- TFieldPredicate IsInlined;
- };
- inline void PrintInlined(const NProtoBuf::Message& msg, TInliningPrinter<>::TFieldPredicate isInlined, IJsonOutput& output, const TProto2JsonConfig& config = TProto2JsonConfig()) {
- TInliningPrinter<> printer(std::move(isInlined), config);
- printer.Print(msg, output);
- }
- inline TString PrintInlined(const NProtoBuf::Message& msg, TInliningPrinter<>::TFieldPredicate isInlined, const TProto2JsonConfig& config = TProto2JsonConfig()) {
- TString ret;
- PrintInlined(msg, std::move(isInlined), *CreateJsonMapOutput(ret, config), config);
- return ret;
- }
- }
|