• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifndef GOOGLE_PROTOBUF_COMPILER_RUST_ACCESSORS_ACCESSOR_GENERATOR_H__
9 #define GOOGLE_PROTOBUF_COMPILER_RUST_ACCESSORS_ACCESSOR_GENERATOR_H__
10 
11 #include <memory>
12 #include <string>
13 #include <utility>
14 
15 #include "absl/log/absl_check.h"
16 #include "google/protobuf/compiler/rust/accessors/accessor_case.h"
17 #include "google/protobuf/compiler/rust/context.h"
18 #include "google/protobuf/compiler/rust/naming.h"
19 #include "google/protobuf/descriptor.h"
20 
21 namespace google {
22 namespace protobuf {
23 namespace compiler {
24 namespace rust {
25 
26 class AccessorGenerator {
27  public:
28   AccessorGenerator() = default;
29   virtual ~AccessorGenerator() = default;
30 
31   AccessorGenerator(const AccessorGenerator&) = delete;
32   AccessorGenerator(AccessorGenerator&&) = delete;
33   AccessorGenerator& operator=(const AccessorGenerator&) = delete;
34   AccessorGenerator& operator=(AccessorGenerator&&) = delete;
35 
36   // Constructs a generator for the given field.
37   //
38   // Returns `nullptr` if there is no known generator for this field.
39   static std::unique_ptr<AccessorGenerator> For(Context& ctx,
40                                                 const FieldDescriptor& field);
41 
GenerateMsgImpl(Context & ctx,const FieldDescriptor & field,AccessorCase accessor_case)42   void GenerateMsgImpl(Context& ctx, const FieldDescriptor& field,
43                        AccessorCase accessor_case) const {
44     ctx.Emit({{"comment", FieldInfoComment(ctx, field)}}, R"rs(
45       // $comment$
46     )rs");
47     InMsgImpl(ctx, field, accessor_case);
48     ctx.printer().PrintRaw("\n");
49   }
GenerateExternC(Context & ctx,const FieldDescriptor & field)50   void GenerateExternC(Context& ctx, const FieldDescriptor& field) const {
51     ABSL_CHECK(ctx.is_cpp());
52     InExternC(ctx, field);
53     ctx.printer().PrintRaw("\n");
54   }
GenerateThunkCc(Context & ctx,const FieldDescriptor & field)55   void GenerateThunkCc(Context& ctx, const FieldDescriptor& field) const {
56     ABSL_CHECK(ctx.is_cpp());
57     InThunkCc(ctx, field);
58     ctx.printer().PrintRaw("\n");
59   }
60 
61  private:
62   // Note: the virtual functions are duplicated as non-virtual public functions,
63   // so that we can customize prologue and epilogue behavior for these
64   // functions. For example, consider calling `field.printer.WithVars()` as a
65   // prologue to inject variables automatically.
66 
67   // Called inside the `impl Msg {}`, `impl MsgMut {}` and `impl MsgView`
68   // blocks.
InMsgImpl(Context & ctx,const FieldDescriptor & field,AccessorCase accessor_case)69   virtual void InMsgImpl(Context& ctx, const FieldDescriptor& field,
70                          AccessorCase accessor_case) const {}
71 
72   // Called inside of a message's `extern "C" {}` block.
InExternC(Context & ctx,const FieldDescriptor & field)73   virtual void InExternC(Context& ctx, const FieldDescriptor& field) const {}
74 
75   // Called inside of an `extern "C" {}` block in the  `.thunk.cc` file, if such
76   // a file is being generated.
InThunkCc(Context & ctx,const FieldDescriptor & field)77   virtual void InThunkCc(Context& ctx, const FieldDescriptor& field) const {}
78 };
79 
80 class SingularScalar final : public AccessorGenerator {
81  public:
82   ~SingularScalar() override = default;
83   void InMsgImpl(Context& ctx, const FieldDescriptor& field,
84                  AccessorCase accessor_case) const override;
85   void InExternC(Context& ctx, const FieldDescriptor& field) const override;
86   void InThunkCc(Context& ctx, const FieldDescriptor& field) const override;
87 };
88 
89 class SingularString final : public AccessorGenerator {
90  public:
91   ~SingularString() override = default;
92   void InMsgImpl(Context& ctx, const FieldDescriptor& field,
93                  AccessorCase accessor_case) const override;
94   void InExternC(Context& ctx, const FieldDescriptor& field) const override;
95   void InThunkCc(Context& ctx, const FieldDescriptor& field) const override;
96 };
97 
98 class SingularCord final : public AccessorGenerator {
99  public:
100   ~SingularCord() override = default;
101   void InMsgImpl(Context& ctx, const FieldDescriptor& field,
102                  AccessorCase accessor_case) const override;
103   void InExternC(Context& ctx, const FieldDescriptor& field) const override;
104   void InThunkCc(Context& ctx, const FieldDescriptor& field) const override;
105 };
106 
107 class SingularMessage final : public AccessorGenerator {
108  public:
109   ~SingularMessage() override = default;
110   void InMsgImpl(Context& ctx, const FieldDescriptor& field,
111                  AccessorCase accessor_case) const override;
112   void InExternC(Context& ctx, const FieldDescriptor& field) const override;
113   void InThunkCc(Context& ctx, const FieldDescriptor& field) const override;
114 };
115 
116 class RepeatedField final : public AccessorGenerator {
117  public:
118   ~RepeatedField() override = default;
119   void InMsgImpl(Context& ctx, const FieldDescriptor& field,
120                  AccessorCase accessor_case) const override;
121   void InExternC(Context& ctx, const FieldDescriptor& field) const override;
122   void InThunkCc(Context& ctx, const FieldDescriptor& field) const override;
123 };
124 
125 class UnsupportedField final : public AccessorGenerator {
126  public:
UnsupportedField(std::string reason)127   explicit UnsupportedField(std::string reason) : reason_(std::move(reason)) {}
128   ~UnsupportedField() override = default;
129   void InMsgImpl(Context& ctx, const FieldDescriptor& field,
130                  AccessorCase accessor_case) const override;
131 
132  private:
133   std::string reason_;
134 };
135 
136 class Map final : public AccessorGenerator {
137  public:
138   ~Map() override = default;
139   void InMsgImpl(Context& ctx, const FieldDescriptor& field,
140                  AccessorCase accessor_case) const override;
141   void InExternC(Context& ctx, const FieldDescriptor& field) const override;
142   void InThunkCc(Context& ctx, const FieldDescriptor& field) const override;
143 };
144 
145 }  // namespace rust
146 }  // namespace compiler
147 }  // namespace protobuf
148 }  // namespace google
149 
150 #endif  // GOOGLE_PROTOBUF_COMPILER_RUST_ACCESSORS_ACCESSOR_GENERATOR_H__
151