Collect protobuf message descriptor from CSR and compile the descriptor.
(
subject_name: &String,
ccsr_client: &Client,
)
| 2731 | |
| 2732 | /// Collect protobuf message descriptor from CSR and compile the descriptor. |
| 2733 | async fn compile_proto( |
| 2734 | subject_name: &String, |
| 2735 | ccsr_client: &Client, |
| 2736 | ) -> Result<CsrSeedProtobufSchema, PlanError> { |
| 2737 | let (primary_subject, dependency_subjects) = ccsr_client |
| 2738 | .get_subject_and_references(subject_name) |
| 2739 | .await |
| 2740 | .map_err(|e| PlanError::FetchingCsrSchemaFailed { |
| 2741 | schema_lookup: format!("subject {}", subject_name.quoted()), |
| 2742 | cause: Arc::new(e), |
| 2743 | })?; |
| 2744 | |
| 2745 | // Compile .proto files into a file descriptor set. |
| 2746 | let mut source_tree = VirtualSourceTree::new(); |
| 2747 | |
| 2748 | // Add well-known types (e.g., google/protobuf/timestamp.proto) to the source |
| 2749 | // tree. These are implicitly available to protoc but are typically not |
| 2750 | // registered in the schema registry. |
| 2751 | source_tree.as_mut().map_well_known_types(); |
| 2752 | |
| 2753 | for subject in iter::once(&primary_subject).chain(dependency_subjects.iter()) { |
| 2754 | source_tree.as_mut().add_file( |
| 2755 | Path::new(&subject.name), |
| 2756 | subject.schema.raw.as_bytes().to_vec(), |
| 2757 | ); |
| 2758 | } |
| 2759 | let mut db = SourceTreeDescriptorDatabase::new(source_tree.as_mut()); |
| 2760 | let fds = db |
| 2761 | .as_mut() |
| 2762 | .build_file_descriptor_set(&[Path::new(&primary_subject.name)]) |
| 2763 | .map_err(|cause| PlanError::InvalidProtobufSchema { cause })?; |
| 2764 | |
| 2765 | // Ensure there is exactly one message in the file. |
| 2766 | let primary_fd = fds.file(0); |
| 2767 | let message_name = match primary_fd.message_type_size() { |
| 2768 | 1 => String::from_utf8_lossy(primary_fd.message_type(0).name()).into_owned(), |
| 2769 | 0 => bail_unsupported!(29603, "Protobuf schemas with no messages"), |
| 2770 | _ => bail_unsupported!(29603, "Protobuf schemas with multiple messages"), |
| 2771 | }; |
| 2772 | |
| 2773 | // Encode the file descriptor set into a SQL byte string. |
| 2774 | let bytes = &fds |
| 2775 | .serialize() |
| 2776 | .map_err(|cause| PlanError::InvalidProtobufSchema { cause })?; |
| 2777 | let mut schema = String::new(); |
| 2778 | strconv::format_bytes(&mut schema, bytes); |
| 2779 | |
| 2780 | Ok(CsrSeedProtobufSchema { |
| 2781 | schema, |
| 2782 | message_name, |
| 2783 | }) |
| 2784 | } |
| 2785 | |
| 2786 | const MZ_NOW_NAME: &str = "mz_now"; |
| 2787 | const MZ_NOW_SCHEMA: &str = "mz_catalog"; |
no test coverage detected