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