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 #include "google/protobuf/compiler/rust/accessors/accessors.h"
9
10 #include <memory>
11
12 #include "absl/log/absl_log.h"
13 #include "google/protobuf/compiler/rust/accessors/accessor_case.h"
14 #include "google/protobuf/compiler/rust/accessors/generator.h"
15 #include "google/protobuf/compiler/rust/context.h"
16 #include "google/protobuf/compiler/rust/rust_field_type.h"
17 #include "google/protobuf/descriptor.h"
18 #include "google/protobuf/descriptor.pb.h"
19 #include "google/protobuf/port.h"
20
21 namespace google {
22 namespace protobuf {
23 namespace compiler {
24 namespace rust {
25
26 namespace {
27
AccessorGeneratorFor(Context & ctx,const FieldDescriptor & field)28 std::unique_ptr<AccessorGenerator> AccessorGeneratorFor(
29 Context& ctx, const FieldDescriptor& field) {
30 // TODO: We do not support ctype=CORD fields or repeated
31 // ctype=STRING_PIECE fields on cpp kernel yet (upb doesn't care about ctype).
32 auto ctype = field.options().ctype();
33 if (ctx.is_cpp() &&
34 (ctype == FieldOptions::CORD || ctype == FieldOptions::STRING_PIECE) &&
35 field.is_repeated()) {
36 return std::make_unique<UnsupportedField>(
37 "fields has an unsupported ctype");
38 }
39
40 if (field.is_map()) {
41 return std::make_unique<Map>();
42 }
43
44 if (field.is_repeated()) {
45 return std::make_unique<RepeatedField>();
46 }
47
48 switch (GetRustFieldType(field)) {
49 case RustFieldType::INT32:
50 case RustFieldType::INT64:
51 case RustFieldType::UINT32:
52 case RustFieldType::UINT64:
53 case RustFieldType::FLOAT:
54 case RustFieldType::DOUBLE:
55 case RustFieldType::BOOL:
56 case RustFieldType::ENUM:
57 return std::make_unique<SingularScalar>();
58 case RustFieldType::BYTES:
59 case RustFieldType::STRING:
60 if (ctype == FieldOptions::CORD) {
61 return std::make_unique<SingularCord>();
62 }
63 return std::make_unique<SingularString>();
64 case RustFieldType::MESSAGE:
65 return std::make_unique<SingularMessage>();
66 }
67
68 ABSL_LOG(ERROR) << "Unknown field type: " << field.type();
69 internal::Unreachable();
70 }
71
72 } // namespace
73
GenerateAccessorMsgImpl(Context & ctx,const FieldDescriptor & field,AccessorCase accessor_case)74 void GenerateAccessorMsgImpl(Context& ctx, const FieldDescriptor& field,
75 AccessorCase accessor_case) {
76 AccessorGeneratorFor(ctx, field)->GenerateMsgImpl(ctx, field, accessor_case);
77 }
78
GenerateAccessorExternC(Context & ctx,const FieldDescriptor & field)79 void GenerateAccessorExternC(Context& ctx, const FieldDescriptor& field) {
80 AccessorGeneratorFor(ctx, field)->GenerateExternC(ctx, field);
81 }
82
GenerateAccessorThunkCc(Context & ctx,const FieldDescriptor & field)83 void GenerateAccessorThunkCc(Context& ctx, const FieldDescriptor& field) {
84 AccessorGeneratorFor(ctx, field)->GenerateThunkCc(ctx, field);
85 }
86
87 } // namespace rust
88 } // namespace compiler
89 } // namespace protobuf
90 } // namespace google
91