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 "upb/reflection/internal/service_def.h"
9
10 #include "upb/reflection/def_type.h"
11 #include "upb/reflection/internal/def_builder.h"
12 #include "upb/reflection/internal/file_def.h"
13 #include "upb/reflection/internal/method_def.h"
14
15 // Must be last.
16 #include "upb/port/def.inc"
17
18 struct upb_ServiceDef {
19 const UPB_DESC(ServiceOptions*) opts;
20 const UPB_DESC(FeatureSet*) resolved_features;
21 const upb_FileDef* file;
22 const char* full_name;
23 upb_MethodDef* methods;
24 int method_count;
25 int index;
26 #if UINTPTR_MAX == 0xffffffff
27 uint32_t padding; // Increase size to a multiple of 8.
28 #endif
29 };
30
_upb_ServiceDef_At(const upb_ServiceDef * s,int index)31 upb_ServiceDef* _upb_ServiceDef_At(const upb_ServiceDef* s, int index) {
32 return (upb_ServiceDef*)&s[index];
33 }
34
UPB_DESC(ServiceOptions)35 const UPB_DESC(ServiceOptions) *
36 upb_ServiceDef_Options(const upb_ServiceDef* s) {
37 return s->opts;
38 }
39
upb_ServiceDef_HasOptions(const upb_ServiceDef * s)40 bool upb_ServiceDef_HasOptions(const upb_ServiceDef* s) {
41 return s->opts != (void*)kUpbDefOptDefault;
42 }
43
UPB_DESC(FeatureSet)44 const UPB_DESC(FeatureSet) *
45 upb_ServiceDef_ResolvedFeatures(const upb_ServiceDef* s) {
46 return s->resolved_features;
47 }
48
upb_ServiceDef_FullName(const upb_ServiceDef * s)49 const char* upb_ServiceDef_FullName(const upb_ServiceDef* s) {
50 return s->full_name;
51 }
52
upb_ServiceDef_Name(const upb_ServiceDef * s)53 const char* upb_ServiceDef_Name(const upb_ServiceDef* s) {
54 return _upb_DefBuilder_FullToShort(s->full_name);
55 }
56
upb_ServiceDef_Index(const upb_ServiceDef * s)57 int upb_ServiceDef_Index(const upb_ServiceDef* s) { return s->index; }
58
upb_ServiceDef_File(const upb_ServiceDef * s)59 const upb_FileDef* upb_ServiceDef_File(const upb_ServiceDef* s) {
60 return s->file;
61 }
62
upb_ServiceDef_MethodCount(const upb_ServiceDef * s)63 int upb_ServiceDef_MethodCount(const upb_ServiceDef* s) {
64 return s->method_count;
65 }
66
upb_ServiceDef_Method(const upb_ServiceDef * s,int i)67 const upb_MethodDef* upb_ServiceDef_Method(const upb_ServiceDef* s, int i) {
68 return (i < 0 || i >= s->method_count) ? NULL
69 : _upb_MethodDef_At(s->methods, i);
70 }
71
upb_ServiceDef_FindMethodByName(const upb_ServiceDef * s,const char * name)72 const upb_MethodDef* upb_ServiceDef_FindMethodByName(const upb_ServiceDef* s,
73 const char* name) {
74 for (int i = 0; i < s->method_count; i++) {
75 const upb_MethodDef* m = _upb_MethodDef_At(s->methods, i);
76 if (strcmp(name, upb_MethodDef_Name(m)) == 0) {
77 return m;
78 }
79 }
80 return NULL;
81 }
82
create_service(upb_DefBuilder * ctx,const UPB_DESC (ServiceDescriptorProto *)svc_proto,const UPB_DESC (FeatureSet *)parent_features,upb_ServiceDef * s)83 static void create_service(upb_DefBuilder* ctx,
84 const UPB_DESC(ServiceDescriptorProto*) svc_proto,
85 const UPB_DESC(FeatureSet*) parent_features,
86 upb_ServiceDef* s) {
87 UPB_DEF_SET_OPTIONS(s->opts, ServiceDescriptorProto, ServiceOptions,
88 svc_proto);
89 s->resolved_features = _upb_DefBuilder_ResolveFeatures(
90 ctx, parent_features, UPB_DESC(ServiceOptions_features)(s->opts));
91
92 // Must happen before _upb_DefBuilder_Add()
93 s->file = _upb_DefBuilder_File(ctx);
94
95 upb_StringView name = UPB_DESC(ServiceDescriptorProto_name)(svc_proto);
96 const char* package = _upb_FileDef_RawPackage(s->file);
97 s->full_name = _upb_DefBuilder_MakeFullName(ctx, package, name);
98 _upb_DefBuilder_Add(ctx, s->full_name,
99 _upb_DefType_Pack(s, UPB_DEFTYPE_SERVICE));
100
101 size_t n;
102 const UPB_DESC(MethodDescriptorProto)* const* methods =
103 UPB_DESC(ServiceDescriptorProto_method)(svc_proto, &n);
104 s->method_count = n;
105 s->methods = _upb_MethodDefs_New(ctx, n, methods, s->resolved_features, s);
106 }
107
_upb_ServiceDefs_New(upb_DefBuilder * ctx,int n,const UPB_DESC (ServiceDescriptorProto *)const * protos,const UPB_DESC (FeatureSet *)parent_features)108 upb_ServiceDef* _upb_ServiceDefs_New(upb_DefBuilder* ctx, int n,
109 const UPB_DESC(ServiceDescriptorProto*)
110 const* protos,
111 const UPB_DESC(FeatureSet*)
112 parent_features) {
113 _upb_DefType_CheckPadding(sizeof(upb_ServiceDef));
114
115 upb_ServiceDef* s = _upb_DefBuilder_Alloc(ctx, sizeof(upb_ServiceDef) * n);
116 for (int i = 0; i < n; i++) {
117 create_service(ctx, protos[i], parent_features, &s[i]);
118 s[i].index = i;
119 }
120 return s;
121 }
122