1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2023 Google LLC. All rights reserved.
3 //
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file or at
6 // https://developers.google.com/open-source/licenses/bsd
7
8 #include "google/protobuf/compiler/hpb/gen_extensions.h"
9
10 #include "absl/strings/str_cat.h"
11 #include "google/protobuf/compiler/hpb/gen_utils.h"
12 #include "google/protobuf/compiler/hpb/names.h"
13
14 namespace google::protobuf::hpb_generator {
15
16 namespace protobuf = ::proto2;
17
ExtensionIdentifierBase(const protobuf::FieldDescriptor * ext)18 std::string ExtensionIdentifierBase(const protobuf::FieldDescriptor* ext) {
19 assert(ext->is_extension());
20 std::string ext_scope;
21 if (ext->extension_scope()) {
22 return MessageName(ext->extension_scope());
23 } else {
24 return ToCIdent(ext->file()->package());
25 }
26 }
27
ContainingTypeName(const protobuf::FieldDescriptor * ext)28 std::string ContainingTypeName(const protobuf::FieldDescriptor* ext) {
29 return ext->containing_type()->file() != ext->file()
30 ? QualifiedClassName(ext->containing_type())
31 : ClassName(ext->containing_type());
32 }
33
WriteExtensionIdentifierHeader(const protobuf::FieldDescriptor * ext,Output & output)34 void WriteExtensionIdentifierHeader(const protobuf::FieldDescriptor* ext,
35 Output& output) {
36 std::string mini_table_name =
37 absl::StrCat(ExtensionIdentifierBase(ext), "_", ext->name(), "_ext");
38 if (ext->extension_scope()) {
39 output(
40 R"cc(
41 static const ::hpb::internal::ExtensionIdentifier<$0, $1> $2;
42 )cc",
43 ContainingTypeName(ext), CppTypeParameterName(ext), ext->name());
44 } else {
45 output(
46 R"cc(
47 extern const ::hpb::internal::ExtensionIdentifier<$0, $1> $2;
48 )cc",
49 ContainingTypeName(ext), CppTypeParameterName(ext), ext->name());
50 }
51 }
52
WriteExtensionIdentifiersHeader(const std::vector<const protobuf::FieldDescriptor * > & extensions,Output & output)53 void WriteExtensionIdentifiersHeader(
54 const std::vector<const protobuf::FieldDescriptor*>& extensions,
55 Output& output) {
56 for (const auto* ext : extensions) {
57 if (!ext->extension_scope()) {
58 WriteExtensionIdentifierHeader(ext, output);
59 }
60 }
61 }
62
WriteExtensionIdentifier(const protobuf::FieldDescriptor * ext,Output & output)63 void WriteExtensionIdentifier(const protobuf::FieldDescriptor* ext,
64 Output& output) {
65 std::string mini_table_name =
66 absl::StrCat(ExtensionIdentifierBase(ext), "_", ext->name(), "_ext");
67 if (ext->extension_scope()) {
68 output(
69 R"cc(
70 const hpb::internal::ExtensionIdentifier<$0, $3> $4::$2(&$1);
71 )cc",
72 ContainingTypeName(ext), mini_table_name, ext->name(),
73 CppTypeParameterName(ext), ClassName(ext->extension_scope()));
74 } else {
75 output(
76 R"cc(
77 const hpb::internal::ExtensionIdentifier<$0, $3> $2(&$1);
78 )cc",
79 ContainingTypeName(ext), mini_table_name, ext->name(),
80 CppTypeParameterName(ext));
81 }
82 }
83
WriteExtensionIdentifiers(const std::vector<const protobuf::FieldDescriptor * > & extensions,Output & output)84 void WriteExtensionIdentifiers(
85 const std::vector<const protobuf::FieldDescriptor*>& extensions,
86 Output& output) {
87 for (const auto* ext : extensions) {
88 if (!ext->extension_scope()) {
89 WriteExtensionIdentifier(ext, output);
90 }
91 }
92 }
93
94 } // namespace protobuf
95 } // namespace google::hpb_generator
96