MCPcopy Create free account
hub / github.com/davidgiven/fluxengine / resolveProtoPath

Function resolveProtoPath

lib/config/proto.cc:87–153  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

85}
86
87static ProtoField resolveProtoPath(
88 google::protobuf::Message* message, const std::string& path, bool create)
89{
90 std::string::size_type dot = path.rfind('.');
91 std::string leading = (dot == std::string::npos) ? "" : path.substr(0, dot);
92 std::string trailing =
93 (dot == std::string::npos) ? path : path.substr(dot + 1);
94
95 auto fail = [&]()
96 {
97 throw ProtoPathNotFoundException(
98 fmt::format("no such config field '{}' in '{}'", trailing, path));
99 };
100
101 const auto* descriptor = message->GetDescriptor();
102
103 std::string item;
104 std::stringstream ss(leading);
105 while (std::getline(ss, item, '.'))
106 {
107 static const std::regex INDEX_REGEX("(\\w+)\\[([0-9]+)\\]");
108
109 int index = splitIndexedField(item);
110
111 const auto* field = descriptor->FindFieldByName(item);
112 if (!field)
113 throw ProtoPathNotFoundException(
114 fmt::format("no such config field '{}' in '{}'", item, path));
115 if (field->type() != google::protobuf::FieldDescriptor::TYPE_MESSAGE)
116 throw ProtoPathNotFoundException(fmt::format(
117 "config field '{}' in '{}' is not a message", item, path));
118
119 const auto* reflection = message->GetReflection();
120 if (!field->is_repeated() && (index != -1))
121 throw ProtoPathNotFoundException(fmt::format(
122 "config field '{}[{}]' is indexed, but not repeated",
123 item,
124 index));
125
126 if (field->is_repeated())
127 {
128 if (index == -1)
129 throw ProtoPathNotFoundException(fmt::format(
130 "config field '{}' is repeated and must be indexed", item));
131 while (reflection->FieldSize(*message, field) <= index)
132 reflection->AddMessage(message, field);
133
134 message = reflection->MutableRepeatedMessage(message, field, index);
135 }
136 else
137 {
138 if (!create && !reflection->HasField(*message, field))
139 throw ProtoPathNotFoundException(fmt::format(
140 "could not find config field '{}'", field->name()));
141 message = reflection->MutableMessage(message, field);
142 }
143
144 descriptor = message->GetDescriptor();

Callers 2

makeProtoPathFunction · 0.85
findProtoPathFunction · 0.85

Calls 3

splitIndexedFieldFunction · 0.85
ProtoFieldClass · 0.85

Tested by

no test coverage detected