-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add CelDescriptorPool and ProtoMessageFactory.
PiperOrigin-RevId: 572023058
- Loading branch information
1 parent
67053b3
commit 1ba80a0
Showing
11 changed files
with
768 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
46 changes: 46 additions & 0 deletions
46
common/src/main/java/dev/cel/common/internal/CelDescriptorPool.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
// Copyright 2023 Google LLC | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// https://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package dev.cel.common.internal; | ||
|
||
import com.google.errorprone.annotations.Immutable; | ||
import com.google.protobuf.Descriptors.Descriptor; | ||
import com.google.protobuf.Descriptors.FieldDescriptor; | ||
import com.google.protobuf.ExtensionRegistry; | ||
import dev.cel.common.annotations.Internal; | ||
import java.util.Optional; | ||
|
||
/** | ||
* {@link CelDescriptorPool} allows lookup of descriptors for message types and field descriptors | ||
* for Proto2 extension messages. | ||
* | ||
* <p>CEL Library Internals. Do Not Use. | ||
*/ | ||
@Immutable | ||
@Internal | ||
public interface CelDescriptorPool { | ||
|
||
/** Finds the descriptor by fully qualified message type. */ | ||
Optional<Descriptor> findDescriptor(String name); | ||
|
||
/** Finds the corresponding field descriptor for an extension field on a message. */ | ||
Optional<FieldDescriptor> findExtensionDescriptor( | ||
Descriptor containingDescriptor, String fieldName); | ||
|
||
/** | ||
* Retrieves the registered extension registry. This is specifically needed to handle unpacking | ||
* Any messages containing Proto2 extension messages. | ||
*/ | ||
ExtensionRegistry getExtensionRegistry(); | ||
} |
85 changes: 85 additions & 0 deletions
85
common/src/main/java/dev/cel/common/internal/CombinedDescriptorPool.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
// Copyright 2023 Google LLC | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// https://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package dev.cel.common.internal; | ||
|
||
import com.google.common.collect.ImmutableList; | ||
import com.google.errorprone.annotations.Immutable; | ||
import com.google.protobuf.Descriptors.Descriptor; | ||
import com.google.protobuf.Descriptors.FieldDescriptor; | ||
import com.google.protobuf.ExtensionRegistry; | ||
import dev.cel.common.annotations.Internal; | ||
import java.util.Optional; | ||
|
||
/** | ||
* The {@link CombinedDescriptorPool} takes one or more {@link CelDescriptorPool} instances and | ||
* supports descriptor lookups in the order the descriptor pools are added to the constructor. | ||
* | ||
* <p>CEL Library Internals. Do Not Use. | ||
*/ | ||
@Immutable | ||
@Internal | ||
public final class CombinedDescriptorPool implements CelDescriptorPool { | ||
private final ImmutableList<CelDescriptorPool> descriptorPools; | ||
|
||
@SuppressWarnings("Immutable") // ExtensionRegistry is immutable, just not marked as such. | ||
private final ExtensionRegistry extensionRegistry; | ||
|
||
public static CombinedDescriptorPool create(ImmutableList<CelDescriptorPool> descriptorPools) { | ||
return new CombinedDescriptorPool(descriptorPools); | ||
} | ||
|
||
@Override | ||
public Optional<Descriptor> findDescriptor(String name) { | ||
for (CelDescriptorPool descriptorPool : descriptorPools) { | ||
Optional<Descriptor> maybeDescriptor = descriptorPool.findDescriptor(name); | ||
if (maybeDescriptor.isPresent()) { | ||
return maybeDescriptor; | ||
} | ||
} | ||
|
||
return Optional.empty(); | ||
} | ||
|
||
@Override | ||
public Optional<FieldDescriptor> findExtensionDescriptor( | ||
Descriptor containingDescriptor, String fieldName) { | ||
for (CelDescriptorPool descriptorPool : descriptorPools) { | ||
Optional<FieldDescriptor> maybeExtensionDescriptor = | ||
descriptorPool.findExtensionDescriptor(containingDescriptor, fieldName); | ||
if (maybeExtensionDescriptor.isPresent()) { | ||
return maybeExtensionDescriptor; | ||
} | ||
} | ||
|
||
return Optional.empty(); | ||
} | ||
|
||
@Override | ||
public ExtensionRegistry getExtensionRegistry() { | ||
return extensionRegistry; | ||
} | ||
|
||
private CombinedDescriptorPool(ImmutableList<CelDescriptorPool> descriptorPools) { | ||
this.descriptorPools = descriptorPools; | ||
// TODO: Combine the extension registry. This will become necessary once we accept | ||
// ExtensionRegistry through runtime builder. | ||
this.extensionRegistry = | ||
descriptorPools.stream() | ||
.map(CelDescriptorPool::getExtensionRegistry) | ||
.filter(e -> !e.equals(ExtensionRegistry.getEmptyRegistry())) | ||
.findFirst() | ||
.orElse(ExtensionRegistry.getEmptyRegistry()); | ||
} | ||
} |
96 changes: 96 additions & 0 deletions
96
common/src/main/java/dev/cel/common/internal/DefaultDescriptorPool.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
// Copyright 2023 Google LLC | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// https://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package dev.cel.common.internal; | ||
|
||
import static com.google.common.base.Preconditions.checkNotNull; | ||
import static com.google.common.collect.ImmutableMap.toImmutableMap; | ||
import static java.util.Arrays.stream; | ||
|
||
import com.google.common.collect.ImmutableCollection; | ||
import com.google.common.collect.ImmutableMap; | ||
import com.google.common.collect.ImmutableMultimap; | ||
import com.google.errorprone.annotations.Immutable; | ||
import com.google.protobuf.Descriptors.Descriptor; | ||
import com.google.protobuf.Descriptors.FieldDescriptor; | ||
import com.google.protobuf.ExtensionRegistry; | ||
import dev.cel.common.CelDescriptors; | ||
import dev.cel.common.annotations.Internal; | ||
import java.util.HashMap; | ||
import java.util.Map; | ||
import java.util.Optional; | ||
|
||
/** | ||
* A descriptor pool that has descriptors pre-loaded for well-known types defined by {@link | ||
* WellKnownProto}. | ||
* | ||
* <p>CEL Library Internals. Do Not Use. | ||
*/ | ||
@Immutable | ||
@Internal | ||
public final class DefaultDescriptorPool implements CelDescriptorPool { | ||
private static final ImmutableMap<String, Descriptor> WELL_KNOWN_TYPE_DESCRIPTORS = | ||
stream(WellKnownProto.values()) | ||
.collect(toImmutableMap(WellKnownProto::typeName, WellKnownProto::descriptor)); | ||
|
||
/** A DefaultDescriptorPool instance with just well known types loaded. */ | ||
public static final DefaultDescriptorPool INSTANCE = | ||
new DefaultDescriptorPool(WELL_KNOWN_TYPE_DESCRIPTORS, ImmutableMultimap.of()); | ||
|
||
// K: Fully qualified message type name, V: Message descriptor | ||
private final ImmutableMap<String, Descriptor> descriptorMap; | ||
|
||
// K: Fully qualified message type name (of containing descriptor) | ||
// V: Field descriptor for the extension message | ||
private final ImmutableMultimap<String, FieldDescriptor> extensionDescriptorMap; | ||
|
||
public static DefaultDescriptorPool create(CelDescriptors celDescriptors) { | ||
Map<String, Descriptor> descriptorMap = new HashMap<>(); // Using a hashmap to allow deduping | ||
stream(WellKnownProto.values()).forEach(d -> descriptorMap.put(d.typeName(), d.descriptor())); | ||
|
||
for (Descriptor descriptor : celDescriptors.messageTypeDescriptors()) { | ||
descriptorMap.putIfAbsent(descriptor.getFullName(), descriptor); | ||
} | ||
|
||
return new DefaultDescriptorPool( | ||
ImmutableMap.copyOf(descriptorMap), celDescriptors.extensionDescriptors()); | ||
} | ||
|
||
@Override | ||
public Optional<Descriptor> findDescriptor(String name) { | ||
return Optional.ofNullable(descriptorMap.get(name)); | ||
} | ||
|
||
@Override | ||
public Optional<FieldDescriptor> findExtensionDescriptor( | ||
Descriptor containingDescriptor, String fieldName) { | ||
String typeName = containingDescriptor.getFullName(); | ||
ImmutableCollection<FieldDescriptor> fieldDescriptors = extensionDescriptorMap.get(typeName); | ||
|
||
return fieldDescriptors.stream().filter(d -> d.getFullName().equals(fieldName)).findFirst(); | ||
} | ||
|
||
@Override | ||
public ExtensionRegistry getExtensionRegistry() { | ||
// TODO: Populate one from runtime builder. | ||
return ExtensionRegistry.getEmptyRegistry(); | ||
} | ||
|
||
private DefaultDescriptorPool( | ||
ImmutableMap<String, Descriptor> descriptorMap, | ||
ImmutableMultimap<String, FieldDescriptor> extensionDescriptorMap) { | ||
this.descriptorMap = checkNotNull(descriptorMap); | ||
this.extensionDescriptorMap = checkNotNull(extensionDescriptorMap); | ||
} | ||
} |
Oops, something went wrong.