1818
1919import com .google .auto .value .AutoValue ;
2020import com .google .auto .value .extension .memoized .Memoized ;
21- import com .google .common .collect .ImmutableMap ;
2221import com .google .errorprone .annotations .Immutable ;
2322import com .google .protobuf .ByteString ;
2423import com .google .protobuf .MessageLite ;
24+ import dev .cel .common .exceptions .CelAttributeNotFoundException ;
2525import dev .cel .common .types .CelType ;
2626import dev .cel .common .types .StructTypeReference ;
2727import dev .cel .protobuf .CelLiteDescriptor .FieldLiteDescriptor ;
@@ -93,16 +93,6 @@ ByteString toByteString() {
9393 return bytes != null ? bytes : serializedRawValue ();
9494 }
9595
96- @ Memoized
97- ImmutableMap <String , Object > fieldValues () {
98- try {
99- return protoLiteCelValueConverter ().readAllFields (toByteString (), celType ().name ());
100- } catch (IOException e ) {
101- throw new IllegalArgumentException (
102- "Failed to decode proto message of type: " + celType ().name (), e );
103- }
104- }
105-
10696 @ Override
10797 public boolean isZeroValue () {
10898 ByteString bytes = wireBytes ();
@@ -131,28 +121,39 @@ public final int hashCode() {
131121
132122 @ Override
133123 public Object select (String field ) {
134- return find (field )
135- .orElseGet (() -> protoLiteCelValueConverter ().getDefaultCelValue (celType ().name (), field ));
124+ Optional <FieldLiteDescriptor > fd = findFieldDescriptor (field );
125+ if (!fd .isPresent ()) {
126+ throw CelAttributeNotFoundException .of (
127+ String .format ("field '%s' is not declared in message '%s'" , field , celType ().name ()));
128+ }
129+ Object fieldValue = readField (fd .get ());
130+ return fieldValue != null
131+ ? fieldValue
132+ : protoLiteCelValueConverter ().getDefaultCelValue (fd .get ());
136133 }
137134
138135 @ Override
139136 public Optional <Object > find (String field ) {
140- return Optional .ofNullable (fieldValues ().get (field ))
141- .map (protoLiteCelValueConverter ()::resolveFieldValue );
137+ Optional <FieldLiteDescriptor > fd = findFieldDescriptor (field );
138+ if (!fd .isPresent ()) {
139+ // Per SelectableValue#find, a field that doesn't exist is reported as absent.
140+ return Optional .empty ();
141+ }
142+ return Optional .ofNullable (readField (fd .get ()));
142143 }
143144
144145 @ Override
145146 public Object selectByFieldNumber (SelectField field ) {
146- FieldLiteDescriptor fd = findFieldDescriptor (field );
147- if (fd != null ) {
148- Object known = readField (fd );
147+ Optional < FieldLiteDescriptor > fd = findFieldDescriptor (field );
148+ if (fd . isPresent () ) {
149+ Object known = readField (fd . get () );
149150 if (known != null ) {
150151 return known ;
151152 }
152153 if (field .defaultValue () != null ) {
153154 return field .defaultValue ();
154155 }
155- return protoLiteCelValueConverter ().getDefaultCelValue (fd );
156+ return protoLiteCelValueConverter ().getDefaultCelValue (fd . get () );
156157 }
157158 try {
158159 return protoLiteCelValueConverter ().selectByFieldNumber (toByteString (), field );
@@ -164,9 +165,9 @@ public Object selectByFieldNumber(SelectField field) {
164165
165166 @ Override
166167 public boolean hasFieldByNumber (SelectField field ) {
167- FieldLiteDescriptor fd = findFieldDescriptor (field );
168- if (fd != null ) {
169- return hasField (fd );
168+ Optional < FieldLiteDescriptor > fd = findFieldDescriptor (field );
169+ if (fd . isPresent () ) {
170+ return hasField (fd . get () );
170171 }
171172 try {
172173 return protoLiteCelValueConverter ().hasFieldByNumber (toByteString (), field );
@@ -178,9 +179,9 @@ public boolean hasFieldByNumber(SelectField field) {
178179
179180 @ Override
180181 public Optional <Object > findByFieldNumber (SelectField field ) {
181- FieldLiteDescriptor fd = findFieldDescriptor (field );
182- if (fd != null ) {
183- return Optional .ofNullable (readField (fd ));
182+ Optional < FieldLiteDescriptor > fd = findFieldDescriptor (field );
183+ if (fd . isPresent () ) {
184+ return Optional .ofNullable (readField (fd . get () ));
184185 }
185186 try {
186187 return protoLiteCelValueConverter ().findByFieldNumber (toByteString (), field );
@@ -208,10 +209,12 @@ private boolean hasField(FieldLiteDescriptor fd) {
208209 }
209210 }
210211
211- private @ Nullable FieldLiteDescriptor findFieldDescriptor (SelectField field ) {
212- return protoLiteCelValueConverter ()
213- .findFieldDescriptor (celType ().name (), field .fieldNumber ())
214- .orElse (null );
212+ private Optional <FieldLiteDescriptor > findFieldDescriptor (SelectField field ) {
213+ return protoLiteCelValueConverter ().findFieldDescriptor (celType ().name (), field .fieldNumber ());
214+ }
215+
216+ private Optional <FieldLiteDescriptor > findFieldDescriptor (String fieldName ) {
217+ return protoLiteCelValueConverter ().findFieldDescriptor (celType ().name (), fieldName );
215218 }
216219
217220 static ProtoMessageLiteValue create (
0 commit comments