aboutsummaryrefslogtreecommitdiffstats
path: root/yql/essentials/minikql/protobuf_udf/module.cpp
blob: 95befe2220e51a6bd9b90a382110fc8b06085c53 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#include "module.h"

namespace NYql {
namespace NUdf {

using namespace NProtoBuf;

void TProtobufBase::CleanupOnTerminate() const {
}

void TProtobufBase::GetAllFunctions(IFunctionsSink& sink) const {
    sink.Add(TStringRef::Of("Parse"));
    sink.Add(TStringRef::Of("ParseText"));
    sink.Add(TStringRef::Of("Serialize"));
    sink.Add(TStringRef::Of("SerializeText"));
}

void TProtobufBase::BuildFunctionTypeInfo(
        const TStringRef& name,
        TType* userType,
        const TStringRef& typeConfig,
        ui32 flags,
        IFunctionTypeInfoBuilder& builder) const
{
    Y_UNUSED(userType);
    Y_UNUSED(typeConfig);

    try {
        TProtoInfo typeInfo;
        ProtoTypeBuild(GetDescriptor(),
                       EEnumFormat::Number,
                       ERecursionTraits::Fail, true, builder, &typeInfo);

        auto stringType = builder.SimpleType<char*>();

        if ((TStringRef::Of("Serialize") == name) || (TStringRef::Of("SerializeText") == name)) {
            // function signature:
            //    String Serialize(Protobuf value)
            builder.Returns(stringType)
                   .Args()->Add(typeInfo.StructType)
                   .Flags(ICallablePayload::TArgumentFlags::AutoMap)
                   .Done();
        } else {
            // function signature:
            //    Protobuf Parse(String value)
            builder.Returns(typeInfo.StructType)
                   .Args()->Add(stringType)
                   .Flags(ICallablePayload::TArgumentFlags::AutoMap)
                   .Done();
        }


        if (TStringRef::Of("Serialize") == name) {
            if ((flags & TFlags::TypesOnly) == 0) {
                builder.Implementation(this->CreateSerialize(typeInfo, false));
            }
        }
        if (TStringRef::Of("SerializeText") == name) {
            if ((flags & TFlags::TypesOnly) == 0) {
                builder.Implementation(this->CreateSerialize(typeInfo, true));
            }
        }
        if (TStringRef::Of("Parse") == name) {
            if ((flags & TFlags::TypesOnly) == 0) {
                builder.Implementation(this->CreateValue(typeInfo, false));
            }
        }
        if (TStringRef::Of("ParseText") == name) {
            if ((flags & TFlags::TypesOnly) == 0) {
                builder.Implementation(this->CreateValue(typeInfo, true));
            }
        }
    } catch (...) {
        builder.SetError(CurrentExceptionMessage());
    }
}

} // namespace NUdf
} // namespace NYql