• 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 #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