1 | // Protocol Buffers - Google's data interchange format |
2 | // Copyright 2008 Google Inc. All rights reserved. |
3 | // https://developers.google.com/protocol-buffers/ |
4 | // |
5 | // Redistribution and use in source and binary forms, with or without |
6 | // modification, are permitted provided that the following conditions are |
7 | // met: |
8 | // |
9 | // * Redistributions of source code must retain the above copyright |
10 | // notice, this list of conditions and the following disclaimer. |
11 | // * Redistributions in binary form must reproduce the above |
12 | // copyright notice, this list of conditions and the following disclaimer |
13 | // in the documentation and/or other materials provided with the |
14 | // distribution. |
15 | // * Neither the name of Google Inc. nor the names of its |
16 | // contributors may be used to endorse or promote products derived from |
17 | // this software without specific prior written permission. |
18 | // |
19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
20 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
21 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
22 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
23 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
24 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
25 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
26 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
27 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
28 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
29 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
30 | |
31 | // Author: kenton@google.com (Kenton Varda) |
32 | // Based on original Protocol Buffers design by |
33 | // Sanjay Ghemawat, Jeff Dean, and others. |
34 | |
35 | #ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_HELPERS_H__ |
36 | #define GOOGLE_PROTOBUF_COMPILER_CSHARP_HELPERS_H__ |
37 | |
38 | #include <string> |
39 | #include <google/protobuf/port.h> |
40 | #include <google/protobuf/stubs/common.h> |
41 | #include <google/protobuf/descriptor.pb.h> |
42 | #include <google/protobuf/descriptor.h> |
43 | #include <google/protobuf/compiler/code_generator.h> |
44 | #include <google/protobuf/io/printer.h> |
45 | |
46 | #include <google/protobuf/port_def.inc> |
47 | |
48 | namespace google { |
49 | namespace protobuf { |
50 | namespace compiler { |
51 | namespace csharp { |
52 | |
53 | struct Options; |
54 | class FieldGeneratorBase; |
55 | |
56 | // TODO: start using this enum. |
57 | enum CSharpType { |
58 | CSHARPTYPE_INT32 = 1, |
59 | CSHARPTYPE_INT64 = 2, |
60 | CSHARPTYPE_UINT32 = 3, |
61 | CSHARPTYPE_UINT64 = 4, |
62 | CSHARPTYPE_FLOAT = 5, |
63 | CSHARPTYPE_DOUBLE = 6, |
64 | CSHARPTYPE_BOOL = 7, |
65 | CSHARPTYPE_STRING = 8, |
66 | CSHARPTYPE_BYTESTRING = 9, |
67 | CSHARPTYPE_MESSAGE = 10, |
68 | CSHARPTYPE_ENUM = 11, |
69 | MAX_CSHARPTYPE = 11 |
70 | }; |
71 | |
72 | // Converts field type to corresponding C# type. |
73 | CSharpType GetCSharpType(FieldDescriptor::Type type); |
74 | |
75 | std::string StripDotProto(const std::string& proto_file); |
76 | |
77 | // Gets unqualified name of the reflection class |
78 | std::string GetReflectionClassUnqualifiedName(const FileDescriptor* descriptor); |
79 | // Gets unqualified name of the extension class |
80 | std::string GetExtensionClassUnqualifiedName(const FileDescriptor* descriptor); |
81 | |
82 | std::string GetClassName(const EnumDescriptor* descriptor); |
83 | |
84 | std::string GetFieldName(const FieldDescriptor* descriptor); |
85 | |
86 | std::string GetFieldConstantName(const FieldDescriptor* field); |
87 | |
88 | std::string GetPropertyName(const FieldDescriptor* descriptor); |
89 | |
90 | std::string GetOneofCaseName(const FieldDescriptor* descriptor); |
91 | |
92 | int GetFixedSize(FieldDescriptor::Type type); |
93 | |
94 | std::string UnderscoresToCamelCase(const std::string& input, |
95 | bool cap_next_letter, |
96 | bool preserve_period); |
97 | |
98 | inline std::string UnderscoresToCamelCase(const std::string& input, bool cap_next_letter) { |
99 | return UnderscoresToCamelCase(input, cap_next_letter, preserve_period: false); |
100 | } |
101 | |
102 | std::string UnderscoresToPascalCase(const std::string& input); |
103 | |
104 | // Note that we wouldn't normally want to export this (we're not expecting |
105 | // it to be used outside libprotoc itself) but this exposes it for testing. |
106 | std::string PROTOC_EXPORT GetEnumValueName(const std::string& enum_name, |
107 | const std::string& enum_value_name); |
108 | |
109 | // TODO(jtattermusch): perhaps we could move this to strutil |
110 | std::string StringToBase64(const std::string& input); |
111 | |
112 | std::string FileDescriptorToBase64(const FileDescriptor* descriptor); |
113 | |
114 | FieldGeneratorBase* CreateFieldGenerator(const FieldDescriptor* descriptor, |
115 | int presenceIndex, |
116 | const Options* options); |
117 | |
118 | std::string GetFullExtensionName(const FieldDescriptor* descriptor); |
119 | |
120 | bool IsNullable(const FieldDescriptor* descriptor); |
121 | |
122 | // Determines whether the given message is a map entry message, |
123 | // i.e. one implicitly created by protoc due to a map<key, value> field. |
124 | inline bool IsMapEntryMessage(const Descriptor* descriptor) { |
125 | return descriptor->options().map_entry(); |
126 | } |
127 | |
128 | // Checks if this descriptor is for a group and gets its end tag or 0 if it's not a group |
129 | uint GetGroupEndTag(const Descriptor* descriptor); |
130 | |
131 | // Determines whether we're generating code for the proto representation of |
132 | // descriptors etc, for use in the runtime. This is the only type which is |
133 | // allowed to use proto2 syntax, and it generates internal classes. |
134 | inline bool IsDescriptorProto(const FileDescriptor* descriptor) { |
135 | return descriptor->name() == "google/protobuf/descriptor.proto" || |
136 | descriptor->name() == "net/proto2/proto/descriptor.proto" ; |
137 | } |
138 | |
139 | // Determines whether the given message is an options message within descriptor.proto. |
140 | inline bool IsDescriptorOptionMessage(const Descriptor* descriptor) { |
141 | if (!IsDescriptorProto(descriptor: descriptor->file())) { |
142 | return false; |
143 | } |
144 | const std::string name = descriptor->name(); |
145 | return name == "FileOptions" || |
146 | name == "MessageOptions" || |
147 | name == "FieldOptions" || |
148 | name == "OneofOptions" || |
149 | name == "EnumOptions" || |
150 | name == "EnumValueOptions" || |
151 | name == "ServiceOptions" || |
152 | name == "MethodOptions" ; |
153 | } |
154 | |
155 | inline bool IsWrapperType(const FieldDescriptor* descriptor) { |
156 | return descriptor->type() == FieldDescriptor::TYPE_MESSAGE && |
157 | descriptor->message_type()->file()->name() == "google/protobuf/wrappers.proto" ; |
158 | } |
159 | |
160 | inline bool IsProto2(const FileDescriptor* descriptor) { |
161 | return descriptor->syntax() == FileDescriptor::SYNTAX_PROTO2; |
162 | } |
163 | |
164 | inline bool SupportsPresenceApi(const FieldDescriptor* descriptor) { |
165 | // Unlike most languages, we don't generate Has/Clear members for message |
166 | // types, because they can always be set to null in C#. They're not really |
167 | // needed for oneof fields in proto2 either, as everything can be done via |
168 | // oneof case, but we follow the convention from other languages. Proto3 |
169 | // oneof fields never have Has/Clear members - but will also never have |
170 | // the explicit optional keyword either. |
171 | // |
172 | // None of the built-in helpers (descriptor->has_presence() etc) describe |
173 | // quite the behavior we want, so the rules are explicit below. |
174 | |
175 | if (descriptor->is_repeated() || |
176 | descriptor->type() == FieldDescriptor::TYPE_MESSAGE) { |
177 | return false; |
178 | } |
179 | // has_optional_keyword() has more complex rules for proto2, but that |
180 | // doesn't matter given the first part of this condition. |
181 | return IsProto2(descriptor: descriptor->file()) || descriptor->has_optional_keyword(); |
182 | } |
183 | |
184 | inline bool RequiresPresenceBit(const FieldDescriptor* descriptor) { |
185 | return SupportsPresenceApi(descriptor) && |
186 | !IsNullable(descriptor) && |
187 | !descriptor->is_extension() && |
188 | !descriptor->real_containing_oneof(); |
189 | } |
190 | |
191 | } // namespace csharp |
192 | } // namespace compiler |
193 | } // namespace protobuf |
194 | } // namespace google |
195 | |
196 | #include <google/protobuf/port_undef.inc> |
197 | |
198 | #endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_HELPERS_H__ |
199 | |