1414
1515package dev .cel .common .types ;
1616
17- import static com .google .common .collect .ImmutableList .toImmutableList ;
1817import static com .google .common .collect .ImmutableMap .toImmutableMap ;
1918
2019import com .google .common .collect .ImmutableCollection ;
21- import com .google .common .collect .ImmutableList ;
2220import com .google .common .collect .ImmutableMap ;
2321import com .google .common .collect .ImmutableMultimap ;
2422import com .google .common .collect .ImmutableSet ;
3432import dev .cel .common .CelDescriptorUtil ;
3533import dev .cel .common .CelDescriptors ;
3634import dev .cel .common .internal .FileDescriptorSetConverter ;
35+ import java .util .Arrays ;
3736import java .util .Collection ;
3837import java .util .HashMap ;
3938import java .util .Map ;
4039import java .util .Optional ;
41- import java .util .function .Function ;
4240
4341/**
4442 * The {@code ProtoMessageTypeProvider} implements the {@link CelTypeProvider} interface to provide
@@ -68,35 +66,35 @@ public final class ProtoMessageTypeProvider implements CelTypeProvider {
6866 .buildOrThrow ();
6967
7068 private final ImmutableMap <String , CelType > allTypes ;
69+ private final boolean allowJsonFieldNames ;
7170
71+ /** Returns a new builder for {@link ProtoMessageTypeProvider}. */
72+ public static Builder newBuilder () {
73+ return new Builder ();
74+ }
75+
76+ @ Deprecated
7277 public ProtoMessageTypeProvider () {
73- this (CelDescriptors .builder ().build ());
78+ this (CelDescriptors .builder ().build (), false );
7479 }
7580
81+ @ Deprecated
7682 public ProtoMessageTypeProvider (FileDescriptorSet descriptorSet ) {
7783 this (
7884 CelDescriptorUtil .getAllDescriptorsFromFileDescriptor (
79- FileDescriptorSetConverter .convert (descriptorSet )));
85+ FileDescriptorSetConverter .convert (descriptorSet )), false );
8086 }
8187
88+ @ Deprecated
8289 public ProtoMessageTypeProvider (Iterable <Descriptor > descriptors ) {
8390 this (
8491 CelDescriptorUtil .getAllDescriptorsFromFileDescriptor (
85- ImmutableSet .copyOf (Iterables .transform (descriptors , Descriptor ::getFile ))));
92+ ImmutableSet .copyOf (Iterables .transform (descriptors , Descriptor ::getFile ))), false );
8693 }
8794
95+ @ Deprecated
8896 public ProtoMessageTypeProvider (ImmutableSet <FileDescriptor > fileDescriptors ) {
89- this (CelDescriptorUtil .getAllDescriptorsFromFileDescriptor (fileDescriptors ));
90- }
91-
92- public ProtoMessageTypeProvider (CelDescriptors celDescriptors ) {
93- this .allTypes =
94- ImmutableMap .<String , CelType >builder ()
95- .putAll (createEnumTypes (celDescriptors .enumDescriptors ()))
96- .putAll (
97- createProtoMessageTypes (
98- celDescriptors .messageTypeDescriptors (), celDescriptors .extensionDescriptors ()))
99- .buildOrThrow ();
97+ this (CelDescriptorUtil .getAllDescriptorsFromFileDescriptor (fileDescriptors ), false );
10098 }
10199
102100 @ Override
@@ -120,8 +118,14 @@ private ImmutableMap<String, CelType> createProtoMessageTypes(
120118 if (protoMessageTypes .containsKey (descriptor .getFullName ())) {
121119 continue ;
122120 }
123- ImmutableList <String > fieldNames =
124- descriptor .getFields ().stream ().map (FieldDescriptor ::getName ).collect (toImmutableList ());
121+
122+ ImmutableSet .Builder <String > fieldNamesBuilder = ImmutableSet .builder () ;
123+ for (FieldDescriptor fd : descriptor .getFields ()) {
124+ fieldNamesBuilder .add (fd .getName ());
125+ if (allowJsonFieldNames ) {
126+ fieldNamesBuilder .add (fd .getJsonName ());
127+ }
128+ }
125129
126130 Map <String , FieldDescriptor > extensionFields = new HashMap <>();
127131 for (FieldDescriptor extension : extensionMap .get (descriptor .getFullName ())) {
@@ -133,7 +137,7 @@ private ImmutableMap<String, CelType> createProtoMessageTypes(
133137 descriptor .getFullName (),
134138 ProtoMessageType .create (
135139 descriptor .getFullName (),
136- ImmutableSet . copyOf ( fieldNames ),
140+ fieldNamesBuilder . build ( ),
137141 new FieldResolver (this , descriptor )::findField ,
138142 new FieldResolver (this , extensions )::findField ));
139143 }
@@ -158,19 +162,35 @@ private ImmutableMap<String, CelType> createEnumTypes(
158162 }
159163
160164 private static class FieldResolver {
161- private final CelTypeProvider celTypeProvider ;
165+ private final ProtoMessageTypeProvider protoMessageTypeProvider ;
162166 private final ImmutableMap <String , FieldDescriptor > fields ;
163167
164- private FieldResolver (CelTypeProvider celTypeProvider , Descriptor descriptor ) {
168+ private static ImmutableMap <String , FieldDescriptor > collectFieldDescriptorMap (ProtoMessageTypeProvider protoMessageTypeProvider , Descriptor descriptor ) {
169+ ImmutableMap .Builder <String , FieldDescriptor > builder = ImmutableMap .builder ();
170+ for (FieldDescriptor fd : descriptor .getFields ()) {
171+ builder .put (fd .getName (), fd );
172+ if (protoMessageTypeProvider .allowJsonFieldNames ) {
173+ builder .put (fd .getJsonName (), fd );
174+ }
175+ }
176+
177+ return builder .buildKeepingLast ();
178+ }
179+
180+ private FieldResolver (
181+ ProtoMessageTypeProvider protoMessageTypeProvider ,
182+ Descriptor descriptor
183+ ) {
165184 this (
166- celTypeProvider ,
167- descriptor . getFields (). stream ( )
168- . collect ( toImmutableMap ( FieldDescriptor :: getName , Function . identity ())) );
185+ protoMessageTypeProvider ,
186+ collectFieldDescriptorMap ( protoMessageTypeProvider , descriptor )
187+ );
169188 }
170189
171190 private FieldResolver (
172- CelTypeProvider celTypeProvider , ImmutableMap <String , FieldDescriptor > fields ) {
173- this .celTypeProvider = celTypeProvider ;
191+ ProtoMessageTypeProvider protoMessageTypeProvider ,
192+ ImmutableMap <String , FieldDescriptor > fields ) {
193+ this .protoMessageTypeProvider = protoMessageTypeProvider ;
174194 this .fields = fields ;
175195 }
176196
@@ -203,11 +223,11 @@ private Optional<CelType> findFieldInternal(FieldDescriptor fieldDescriptor) {
203223 String messageName = descriptor .getFullName ();
204224 fieldType =
205225 CelTypes .getWellKnownCelType (messageName )
206- .orElse (celTypeProvider .findType (descriptor .getFullName ()).orElse (null ));
226+ .orElse (protoMessageTypeProvider .findType (descriptor .getFullName ()).orElse (null ));
207227 break ;
208228 case ENUM :
209229 EnumDescriptor enumDescriptor = fieldDescriptor .getEnumType ();
210- fieldType = celTypeProvider .findType (enumDescriptor .getFullName ()).orElse (null );
230+ fieldType = protoMessageTypeProvider .findType (enumDescriptor .getFullName ()).orElse (null );
211231 break ;
212232 default :
213233 fieldType = PROTO_TYPE_TO_CEL_TYPE .get (fieldDescriptor .getType ());
@@ -222,4 +242,66 @@ private Optional<CelType> findFieldInternal(FieldDescriptor fieldDescriptor) {
222242 return Optional .of (fieldType );
223243 }
224244 }
245+
246+ /** Builder for {@link ProtoMessageTypeProvider}. */
247+ public static final class Builder {
248+ private final ImmutableSet .Builder <FileDescriptor > fileDescriptors = ImmutableSet .builder ();
249+ private boolean allowJsonFieldNames ;
250+ private CelDescriptors celDescriptors ;
251+
252+ /** Adds a {@link FileDescriptor} to the provider. */
253+ public Builder addFileDescriptors (FileDescriptor ... fileDescriptors ) {
254+ return addFileDescriptors (Arrays .asList (fileDescriptors ));
255+ }
256+
257+ /** Adds a collection of {@link FileDescriptor}s to the provider. */
258+ public Builder addFileDescriptors (Iterable <FileDescriptor > fileDescriptors ) {
259+ this .fileDescriptors .addAll (fileDescriptors );
260+ return this ;
261+ }
262+
263+ /** Adds a collection of {@link Descriptor}s. The parent file of each descriptor is added. */
264+ public Builder addDescriptors (Iterable <Descriptor > descriptors ) {
265+ this .fileDescriptors .addAll (Iterables .transform (descriptors , Descriptor ::getFile ));
266+ return this ;
267+ }
268+
269+ /** Adds a {@link FileDescriptorSet} to the provider. */
270+ public Builder addFileDescriptorSet (FileDescriptorSet fileDescriptorSet ) {
271+ this .fileDescriptors .addAll (FileDescriptorSetConverter .convert (fileDescriptorSet ));
272+ return this ;
273+ }
274+
275+ public Builder setAllowJsonFieldNames (boolean allowJsonFieldNames ) {
276+ this .allowJsonFieldNames = allowJsonFieldNames ;
277+ return this ;
278+ }
279+
280+ public Builder setCelDescriptors (CelDescriptors celDescriptors ) {
281+ this .celDescriptors = celDescriptors ;
282+ return this ;
283+ }
284+
285+ /** Builds the {@link ProtoMessageTypeProvider}. */
286+ public ProtoMessageTypeProvider build () {
287+ // CelDescriptors celDescriptors = CelDescriptorUtil.getAllDescriptorsFromFileDescriptor(fileDescriptors.build());
288+ return new ProtoMessageTypeProvider (celDescriptors , allowJsonFieldNames );
289+ }
290+
291+ private Builder () {}
292+ }
293+
294+ private ProtoMessageTypeProvider (
295+ CelDescriptors celDescriptors ,
296+ boolean allowJsonFieldNames
297+ ) {
298+ this .allowJsonFieldNames = allowJsonFieldNames ;
299+ this .allTypes =
300+ ImmutableMap .<String , CelType >builder ()
301+ .putAll (createEnumTypes (celDescriptors .enumDescriptors ()))
302+ .putAll (
303+ createProtoMessageTypes (
304+ celDescriptors .messageTypeDescriptors (), celDescriptors .extensionDescriptors ()))
305+ .buildOrThrow ();
306+ }
225307}
0 commit comments