YugabyteDB (2.13.0.0-b42, bfc6a6643e7399ac8a0e81d06a3ee6d6571b33ab)

Coverage Report

Created: 2022-03-09 17:30

/Users/deen/code/yugabyte-db/src/yb/gen_yrpc/substitutions.cc
Line
Count
Source (jump to first uncovered line)
1
// Copyright (c) YugaByte, Inc.
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
4
// in compliance with the License.  You may obtain a copy of the License at
5
//
6
// http://www.apache.org/licenses/LICENSE-2.0
7
//
8
// Unless required by applicable law or agreed to in writing, software distributed under the License
9
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
10
// or implied.  See the License for the specific language governing permissions and limitations
11
// under the License.
12
//
13
14
#include "yb/gen_yrpc/substitutions.h"
15
16
#include <boost/algorithm/string/case_conv.hpp>
17
18
#include <google/protobuf/descriptor.h>
19
#include <google/protobuf/descriptor.pb.h>
20
21
#include "yb/gen_yrpc/model.h"
22
23
#include "yb/gutil/strings/util.h"
24
#include "yb/gutil/strings/split.h"
25
26
#include "yb/rpc/service.pb.h"
27
28
#include "yb/util/format.h"
29
30
namespace yb {
31
namespace gen_yrpc {
32
33
namespace {
34
35
const std::string kWireFormat = "::google::protobuf::internal::WireFormatLite";
36
37
// Extract the last filename component.
38
0
std::string GetBaseName(const std::string &path) {
39
0
  size_t last_slash = path.find_last_of("/");
40
0
  return last_slash != string::npos ? path.substr(last_slash + 1) : path;
41
0
}
42
43
0
std::string GenerateOpenNamespace(const std::string& str) {
44
0
  std::string out;
45
0
  for (const auto c : strings::Split(str, ".")) {
46
0
    out += Format("namespace $0 {\n", c);
47
0
  }
48
0
  return out;
49
0
}
50
51
0
std::string GenerateCloseNamespace(const string &str) {
52
0
  std::string out;
53
0
  for (const auto c : strings::Split(str, ".")) {
54
0
    out = Format("} // namespace $0\n", c) + out;
55
0
  }
56
0
  return out;
57
0
}
58
59
} // namespace
60
61
FileSubstitutions::FileSubstitutions(const google::protobuf::FileDescriptor* file)
62
0
    : file_(file), path_no_extension_(RemoveProtoExtension(file->name())) {
63
0
}
64
65
0
Substitutions FileSubstitutions::Create() {
66
0
  std::string path = file_->name();
67
0
  Substitutions result;
68
69
0
  result.emplace_back("path", path);
70
0
  result.emplace_back("path_no_extension", path_no_extension_);
71
72
  // If path = /foo/bar/baz_stuff.proto, base_ = baz_stuff
73
0
  result.emplace_back("base", GetBaseName(path_no_extension_));
74
75
  // If path = /foo/bar/baz_stuff.proto, upper_case_ = BAZ_STUFF
76
0
  std::string upper_case = boost::to_upper_copy(path_no_extension_);
77
0
  std::replace(upper_case.begin(), upper_case.end(), '/', '_');
78
0
  result.emplace_back("upper_case", upper_case);
79
80
0
  result.emplace_back("open_namespace", GenerateOpenNamespace(file_->package()));
81
0
  result.emplace_back("close_namespace", GenerateCloseNamespace(file_->package()));
82
83
0
  result.emplace_back("wire_format", kWireFormat);
84
85
0
  return result;
86
0
}
87
88
0
Substitutions CreateSubstitutions(const google::protobuf::Descriptor* message) {
89
0
  Substitutions result;
90
0
  auto message_name = UnnestedName(message, Lightweight::kFalse, false);
91
0
  result.emplace_back("message_name", message_name);
92
0
  std::string message_pb_name;
93
0
  if (IsLwAny(message)) {
94
0
    message_pb_name = "::google::protobuf::Any";
95
0
  } else if (message->options().map_entry()) {
96
0
    auto key_type = MapFieldType(message->FindFieldByName("key"), Lightweight::kFalse);
97
0
    auto value_type = MapFieldType(message->FindFieldByName("value"), Lightweight::kFalse);
98
0
    message_pb_name = "::google::protobuf::MapPair<" + key_type + ", " + value_type + ">";
99
0
  } else {
100
0
    message_pb_name = message_name;
101
0
  }
102
0
  result.emplace_back("message_pb_name", message_pb_name);
103
0
  result.emplace_back("message_lw_name", UnnestedName(message, Lightweight::kTrue, false));
104
0
  uint32 max_tag = 0;
105
0
  for (int i = 0; i != message->field_count(); ++i) {
106
0
    auto* field = message->field(i);
107
0
    auto wire_type = WireType(field);
108
0
    max_tag = std::max(
109
0
        max_tag, google::protobuf::internal::WireFormatLite::MakeTag(field->number(), wire_type));
110
0
  }
111
112
0
  uint32_t cutoff = 1;
113
0
  while (cutoff < max_tag) {
114
0
    cutoff = cutoff * 2 + 1;
115
0
  }
116
0
  result.emplace_back("cutoff", std::to_string(cutoff));
117
0
  return result;
118
0
}
119
120
Substitutions CreateSubstitutions(
121
0
    const google::protobuf::MethodDescriptor* method, rpc::RpcSides side) {
122
0
  Substitutions result;
123
124
0
  result.emplace_back("rpc_name", method->name());
125
0
  result.emplace_back("rpc_full_name", method->full_name());
126
0
  result.emplace_back("rpc_full_name_plainchars",
127
0
                      StringReplace(method->full_name(), ".", "_", true));
128
129
0
  auto request_type = method->input_type()->full_name();
130
0
  auto response_type = method->output_type()->full_name();
131
0
  if (IsLightweightMethod(method, side)) {
132
0
    request_type = MakeLightweightName(request_type);
133
0
    response_type = MakeLightweightName(response_type);
134
0
    result.emplace_back("params", "RpcCallLWParams");
135
0
  } else {
136
0
    result.emplace_back("params", "RpcCallPBParams");
137
0
  }
138
0
  result.emplace_back("request", RelativeClassPath(request_type, method->service()->full_name()));
139
0
  result.emplace_back(
140
0
      "response", RelativeClassPath(response_type,  method->service()->full_name()));
141
0
  result.emplace_back("metric_enum_key", Format("k$0", method->name()));
142
143
0
  return result;
144
0
}
145
146
0
Substitutions CreateSubstitutions(const google::protobuf::FieldDescriptor* field) {
147
0
  Substitutions result;
148
0
  auto field_name = boost::to_lower_copy(field->name());
149
0
  result.emplace_back("field_name", field_name);
150
0
  result.emplace_back("field_value", field->is_repeated() ? "entry" : field_name + "()");
151
0
  auto camelcase_name = field->camelcase_name();
152
0
  camelcase_name[0] = std::toupper(camelcase_name[0]);
153
0
  result.emplace_back("field_camelcase_name", camelcase_name);
154
0
  std::string field_type = MapFieldType(field, Lightweight::kTrue);
155
0
  const char* message_type_format = "::yb::ArenaList<$0>";
156
0
  result.emplace_back(
157
0
      "field_stored_type",
158
0
      field->is_repeated()
159
0
          ? Format(IsMessage(field) ? message_type_format : "::yb::MCVector<$0>", field_type)
160
0
          : field_type);
161
0
  result.emplace_back("field_type", field_type);
162
0
  result.emplace_back("nonlw_field_type", MapFieldType(field, Lightweight::kFalse));
163
0
  auto field_type_name = "TYPE_" + boost::to_upper_copy(std::string(field->type_name()));
164
0
  result.emplace_back("field_type_name", field_type_name);
165
0
  result.emplace_back("field_number", std::to_string(field->number()));
166
0
  result.emplace_back(
167
0
      "field_serialization",
168
0
      Format("::yb::rpc::LightweightSerialization<$0::$1, $2>",
169
0
             kWireFormat, field_type_name, field_type));
170
0
  result.emplace_back(
171
0
      "field_serialization_prefix",
172
0
      field->is_packed() ? "Packed" : field->is_repeated() ? "Repeated" : "Single");
173
0
  return result;
174
0
}
175
176
0
Substitutions CreateSubstitutions(const google::protobuf::ServiceDescriptor* service) {
177
0
  Substitutions result;
178
0
  result.emplace_back("service_name", service->name());
179
0
  std::string full_service_name = service->full_name();
180
0
  result.emplace_back("original_full_service_name", full_service_name);
181
0
  auto custom_service_name = service->options().GetExtension(rpc::custom_service_name);
182
0
  if (!custom_service_name.empty()) {
183
0
    full_service_name = custom_service_name;
184
0
  }
185
0
  result.emplace_back("full_service_name", full_service_name);
186
0
  result.emplace_back("service_method_count", std::to_string(service->method_count()));
187
0
  result.emplace_back("service_method_enum", service->name() + "RpcMethodIndexes");
188
189
  // TODO: upgrade to protobuf 2.5.x and attach service comments
190
  // to the generated service classes using the SourceLocation API.
191
0
  return result;
192
0
}
193
194
} // namespace gen_yrpc
195
} // namespace yb