• 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 // Author: kenton@google.com (Kenton Varda)
9 //  Based on original Protocol Buffers design by
10 //  Sanjay Ghemawat, Jeff Dean, and others.
11 
12 #ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_HELPERS_H__
13 #define GOOGLE_PROTOBUF_COMPILER_CSHARP_HELPERS_H__
14 
15 #include <string>
16 
17 #include "google/protobuf/compiler/code_generator.h"
18 #include "absl/strings/string_view.h"
19 #include "google/protobuf/compiler/csharp/names.h"
20 #include "google/protobuf/descriptor.h"
21 #include "google/protobuf/descriptor.pb.h"
22 #include "google/protobuf/io/printer.h"
23 #include "google/protobuf/port.h"
24 #include "google/protobuf/port_def.inc"
25 #include "google/protobuf/stubs/common.h"
26 
27 namespace google {
28 namespace protobuf {
29 namespace compiler {
30 namespace csharp {
31 
32 struct Options;
33 class FieldGeneratorBase;
34 
35 // TODO: start using this enum.
36 enum CSharpType {
37   CSHARPTYPE_INT32 = 1,
38   CSHARPTYPE_INT64 = 2,
39   CSHARPTYPE_UINT32 = 3,
40   CSHARPTYPE_UINT64 = 4,
41   CSHARPTYPE_FLOAT = 5,
42   CSHARPTYPE_DOUBLE = 6,
43   CSHARPTYPE_BOOL = 7,
44   CSHARPTYPE_STRING = 8,
45   CSHARPTYPE_BYTESTRING = 9,
46   CSHARPTYPE_MESSAGE = 10,
47   CSHARPTYPE_ENUM = 11,
48   MAX_CSHARPTYPE = 11
49 };
50 
51 // Converts field type to corresponding C# type.
52 CSharpType GetCSharpType(FieldDescriptor::Type type);
53 
54 std::string GetFieldName(const FieldDescriptor* descriptor);
55 
56 std::string GetFieldConstantName(const FieldDescriptor* field);
57 
58 std::string GetPropertyName(const FieldDescriptor* descriptor);
59 
60 std::string GetOneofCaseName(const FieldDescriptor* descriptor);
61 
62 int GetFixedSize(FieldDescriptor::Type type);
63 
64 // Note that we wouldn't normally want to export this (we're not expecting
65 // it to be used outside libprotoc itself) but this exposes it for testing.
66 std::string PROTOC_EXPORT GetEnumValueName(absl::string_view enum_name,
67                                            absl::string_view enum_value_name);
68 
69 // TODO: perhaps we could move this to strutil
70 std::string StringToBase64(absl::string_view input);
71 
72 std::string FileDescriptorToBase64(const FileDescriptor* descriptor);
73 
74 FieldGeneratorBase* CreateFieldGenerator(const FieldDescriptor* descriptor,
75                                          int presenceIndex,
76                                          const Options* options);
77 
78 std::string GetFullExtensionName(const FieldDescriptor* descriptor);
79 
80 bool IsNullable(const FieldDescriptor* descriptor);
81 
82 // Determines whether the given message is a map entry message,
83 // i.e. one implicitly created by protoc due to a map<key, value> field.
IsMapEntryMessage(const Descriptor * descriptor)84 inline bool IsMapEntryMessage(const Descriptor* descriptor) {
85   return descriptor->options().map_entry();
86 }
87 
88 // Determines whether we're generating code for the proto representation of
89 // descriptors etc, for use in the runtime. This is the only type which is
90 // allowed to use proto2 syntax, and it generates internal classes.
IsDescriptorProto(const FileDescriptor * descriptor)91 inline bool IsDescriptorProto(const FileDescriptor* descriptor) {
92   return descriptor->name() == "google/protobuf/descriptor.proto" ||
93          descriptor->name() == "net/proto2/proto/descriptor.proto";
94 }
95 
96 // Determines whether the given message is an options message within descriptor.proto.
IsDescriptorOptionMessage(const Descriptor * descriptor)97 inline bool IsDescriptorOptionMessage(const Descriptor* descriptor) {
98   if (!IsDescriptorProto(descriptor->file())) {
99     return false;
100   }
101   const absl::string_view name = descriptor->name();
102   return name == "FileOptions" ||
103       name == "MessageOptions" ||
104       name == "FieldOptions" ||
105       name == "OneofOptions" ||
106       name == "EnumOptions" ||
107       name == "EnumValueOptions" ||
108       name == "ServiceOptions" ||
109       name == "MethodOptions";
110 }
111 
IsWrapperType(const FieldDescriptor * descriptor)112 inline bool IsWrapperType(const FieldDescriptor* descriptor) {
113   return descriptor->type() == FieldDescriptor::TYPE_MESSAGE &&
114       descriptor->message_type()->file()->name() == "google/protobuf/wrappers.proto";
115 }
116 
SupportsPresenceApi(const FieldDescriptor * descriptor)117 inline bool SupportsPresenceApi(const FieldDescriptor* descriptor) {
118   // Unlike most languages, we don't generate Has/Clear members for message
119   // types, because they can always be set to null in C#. They're not really
120   // needed for oneof fields in proto2 either, as everything can be done via
121   // oneof case, but we follow the convention from other languages.
122   if (descriptor->type() == FieldDescriptor::TYPE_MESSAGE) {
123     return false;
124   }
125 
126   return descriptor->has_presence();
127 }
128 
RequiresPresenceBit(const FieldDescriptor * descriptor)129 inline bool RequiresPresenceBit(const FieldDescriptor* descriptor) {
130   return SupportsPresenceApi(descriptor) &&
131     !IsNullable(descriptor) &&
132     !descriptor->is_extension() &&
133     !descriptor->real_containing_oneof();
134 }
135 
136 }  // namespace csharp
137 }  // namespace compiler
138 }  // namespace protobuf
139 }  // namespace google
140 
141 #include "google/protobuf/port_undef.inc"
142 
143 #endif  // GOOGLE_PROTOBUF_COMPILER_CSHARP_HELPERS_H__
144