• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.  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 // Helper functions for generating ObjectiveC code.
9 
10 #ifndef GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_HELPERS_H__
11 #define GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_HELPERS_H__
12 
13 #include <string>
14 #include <vector>
15 
16 #include "absl/strings/str_cat.h"
17 #include "absl/strings/string_view.h"
18 #include "google/protobuf/compiler/objectivec/options.h"
19 #include "google/protobuf/descriptor.h"
20 #include "google/protobuf/descriptor.pb.h"
21 #include "google/protobuf/io/printer.h"
22 
23 namespace google {
24 namespace protobuf {
25 namespace compiler {
26 namespace objectivec {
27 
28 // Escape C++ trigraphs by escaping question marks to "\?".
29 std::string EscapeTrigraphs(absl::string_view to_escape);
30 
31 // Returns true if the extension field is a custom option.
32 // https://protobuf.dev/programming-guides/proto2/#customoptions
33 bool ExtensionIsCustomOption(const FieldDescriptor* extension_field);
34 
35 enum ObjectiveCType {
36   OBJECTIVECTYPE_INT32,
37   OBJECTIVECTYPE_UINT32,
38   OBJECTIVECTYPE_INT64,
39   OBJECTIVECTYPE_UINT64,
40   OBJECTIVECTYPE_FLOAT,
41   OBJECTIVECTYPE_DOUBLE,
42   OBJECTIVECTYPE_BOOLEAN,
43   OBJECTIVECTYPE_STRING,
44   OBJECTIVECTYPE_DATA,
45   OBJECTIVECTYPE_ENUM,
46   OBJECTIVECTYPE_MESSAGE
47 };
48 
49 enum FlagType {
50   FLAGTYPE_DESCRIPTOR_INITIALIZATION,
51   FLAGTYPE_EXTENSION,
52   FLAGTYPE_FIELD
53 };
54 
55 std::string GetCapitalizedType(const FieldDescriptor* field);
56 
57 ObjectiveCType GetObjectiveCType(FieldDescriptor::Type field_type);
58 
GetObjectiveCType(const FieldDescriptor * field)59 inline ObjectiveCType GetObjectiveCType(const FieldDescriptor* field) {
60   return GetObjectiveCType(field->type());
61 }
62 
IsPrimitiveType(const FieldDescriptor * field)63 inline bool IsPrimitiveType(const FieldDescriptor* field) {
64   ObjectiveCType type = GetObjectiveCType(field);
65   switch (type) {
66     case OBJECTIVECTYPE_INT32:
67     case OBJECTIVECTYPE_UINT32:
68     case OBJECTIVECTYPE_INT64:
69     case OBJECTIVECTYPE_UINT64:
70     case OBJECTIVECTYPE_FLOAT:
71     case OBJECTIVECTYPE_DOUBLE:
72     case OBJECTIVECTYPE_BOOLEAN:
73     case OBJECTIVECTYPE_ENUM:
74       return true;
75       break;
76     default:
77       return false;
78   }
79 }
80 
IsReferenceType(const FieldDescriptor * field)81 inline bool IsReferenceType(const FieldDescriptor* field) {
82   return !IsPrimitiveType(field);
83 }
84 
85 std::string GPBGenericValueFieldName(const FieldDescriptor* field);
86 std::string DefaultValue(const FieldDescriptor* field);
87 
88 std::string BuildFlagsString(FlagType type,
89                              const std::vector<std::string>& strings);
90 
91 // Returns a symbol that can be used in C code to refer to an Objective-C
92 // class without initializing the class.
93 std::string ObjCClass(absl::string_view class_name);
94 
95 // Declares an Objective-C class without initializing the class so that it can
96 // be referred to by ObjCClass.
97 std::string ObjCClassDeclaration(absl::string_view class_name);
98 
99 // Flag to control the behavior of `EmitCommentsString`.
100 enum CommentStringFlags : unsigned int {
101   kCommentStringFlags_None = 0,
102   // Add a newline before the comment.
103   kCommentStringFlags_AddLeadingNewline = 1 << 1,
104   // Force a multiline comment even if only 1 line.
105   kCommentStringFlags_ForceMultiline = 1 << 2,
106 };
107 
108 // Emits HeaderDoc/appledoc style comments out of the comments in the .proto
109 // file.
110 void EmitCommentsString(io::Printer* printer, const GenerationOptions& opts,
111                         const SourceLocation& location,
112                         CommentStringFlags flags = kCommentStringFlags_None);
113 
114 // Emits HeaderDoc/appledoc style comments out of the comments in the .proto
115 // file.
116 template <class TDescriptor>
117 void EmitCommentsString(io::Printer* printer, const GenerationOptions& opts,
118                         const TDescriptor* descriptor,
119                         CommentStringFlags flags = kCommentStringFlags_None) {
120   SourceLocation location;
121   if (descriptor->GetSourceLocation(&location)) {
122     EmitCommentsString(printer, opts, location, flags);
123   }
124 }
125 
126 template <class TDescriptor>
127 std::string GetOptionalDeprecatedAttribute(
128     const TDescriptor* descriptor, const FileDescriptor* file = nullptr) {
129   bool isDeprecated = descriptor->options().deprecated();
130   // The file is only passed when checking Messages & Enums, so those types
131   // get tagged. At the moment, it doesn't seem to make sense to tag every
132   // field or enum value with when the file is deprecated.
133   bool isFileLevelDeprecation = false;
134   if (!isDeprecated && file) {
135     isFileLevelDeprecation = file->options().deprecated();
136     isDeprecated = isFileLevelDeprecation;
137   }
138   if (isDeprecated) {
139     std::string message;
140     const FileDescriptor* sourceFile = descriptor->file();
141     if (isFileLevelDeprecation) {
142       message = absl::StrCat(sourceFile->name(), " is deprecated.");
143     } else {
144       message = absl::StrCat(descriptor->full_name(), " is deprecated (see ",
145                              sourceFile->name(), ").");
146     }
147 
148     return absl::StrCat("GPB_DEPRECATED_MSG(\"", message, "\")");
149   } else {
150     return "";
151   }
152 }
153 
154 // Helpers to identify the WellKnownType files/messages that get an Objective-C
155 // category within the runtime to add helpers.
156 bool HasWKTWithObjCCategory(const FileDescriptor* file);
157 bool IsWKTWithObjCCategory(const Descriptor* descriptor);
158 
159 }  // namespace objectivec
160 }  // namespace compiler
161 }  // namespace protobuf
162 }  // namespace google
163 
164 #endif  // GOOGLE_PROTOBUF_COMPILER_OBJECTIVEC_HELPERS_H__
165