PiperOrigin-RevId: 672084734pull/18171/head
parent
3052de88f8
commit
65c9e69f97
9 changed files with 1 additions and 733 deletions
@ -1,240 +0,0 @@ |
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2023 Google LLC. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file or at
|
||||
// https://developers.google.com/open-source/licenses/bsd
|
||||
|
||||
#include "upb_generator/code_generator_request.h" |
||||
|
||||
#include <inttypes.h> |
||||
|
||||
#include "google/protobuf/compiler/plugin.upb.h" |
||||
#include "upb/mini_descriptor/decode.h" |
||||
#include "upb/mini_table/field.h" |
||||
#include "upb/reflection/def.h" |
||||
|
||||
// Must be last.
|
||||
#include "upb/port/def.inc" |
||||
|
||||
/******************************************************************************/ |
||||
|
||||
// Kitchen sink storage for all of our state as we build the mini descriptors.
|
||||
|
||||
typedef struct { |
||||
upb_Arena* arena; |
||||
upb_Status* status; |
||||
upb_DefPool* symtab; |
||||
|
||||
upb_CodeGeneratorRequest* out; |
||||
|
||||
jmp_buf jmp; |
||||
} upbc_State; |
||||
|
||||
static void upbc_State_Fini(upbc_State* s) { |
||||
if (s->symtab) upb_DefPool_Free(s->symtab); |
||||
} |
||||
|
||||
UPB_NORETURN static void upbc_Error(upbc_State* s, const char* fn, |
||||
const char* msg) { |
||||
upb_Status_SetErrorFormat(s->status, "%s(): %s", fn, msg); |
||||
upbc_State_Fini(s); |
||||
UPB_LONGJMP(s->jmp, -1); |
||||
} |
||||
|
||||
static void upbc_State_Init(upbc_State* s) { |
||||
s->symtab = upb_DefPool_New(); |
||||
if (!s->symtab) upbc_Error(s, __func__, "could not allocate def pool"); |
||||
|
||||
s->out = upb_CodeGeneratorRequest_new(s->arena); |
||||
if (!s->out) upbc_Error(s, __func__, "could not allocate request"); |
||||
} |
||||
|
||||
static upb_StringView upbc_State_StrDup(upbc_State* s, const char* str) { |
||||
upb_StringView from = upb_StringView_FromString(str); |
||||
char* to = upb_Arena_Malloc(s->arena, from.size); |
||||
if (!to) upbc_Error(s, __func__, "Out of memory"); |
||||
memcpy(to, from.data, from.size); |
||||
return upb_StringView_FromDataAndSize(to, from.size); |
||||
} |
||||
|
||||
static void upbc_State_AddMiniDescriptor(upbc_State* s, const char* name, |
||||
upb_StringView encoding) { |
||||
const upb_StringView key = upb_StringView_FromString(name); |
||||
upb_CodeGeneratorRequest_UpbInfo* info = |
||||
upb_CodeGeneratorRequest_UpbInfo_new(s->arena); |
||||
if (!info) upbc_Error(s, __func__, "Out of memory"); |
||||
upb_CodeGeneratorRequest_UpbInfo_set_mini_descriptor(info, encoding); |
||||
bool ok = upb_CodeGeneratorRequest_upb_info_set(s->out, key, info, s->arena); |
||||
if (!ok) upbc_Error(s, __func__, "could not set mini descriptor in map"); |
||||
} |
||||
|
||||
/******************************************************************************/ |
||||
|
||||
// Forward declaration.
|
||||
static void upbc_Scrape_Message(upbc_State*, const upb_MessageDef*); |
||||
|
||||
static void upbc_Scrape_Enum(upbc_State* s, const upb_EnumDef* e) { |
||||
upb_StringView desc; |
||||
bool ok = upb_EnumDef_MiniDescriptorEncode(e, s->arena, &desc); |
||||
if (!ok) upbc_Error(s, __func__, "could not encode enum"); |
||||
|
||||
upbc_State_AddMiniDescriptor(s, upb_EnumDef_FullName(e), desc); |
||||
} |
||||
|
||||
static void upbc_Scrape_Extension(upbc_State* s, const upb_FieldDef* f) { |
||||
upb_StringView desc; |
||||
bool ok = upb_FieldDef_MiniDescriptorEncode(f, s->arena, &desc); |
||||
if (!ok) upbc_Error(s, __func__, "could not encode extension"); |
||||
|
||||
upbc_State_AddMiniDescriptor(s, upb_FieldDef_FullName(f), desc); |
||||
} |
||||
|
||||
static void upbc_Scrape_FileEnums(upbc_State* s, const upb_FileDef* f) { |
||||
const size_t len = upb_FileDef_TopLevelEnumCount(f); |
||||
|
||||
for (size_t i = 0; i < len; i++) { |
||||
upbc_Scrape_Enum(s, upb_FileDef_TopLevelEnum(f, i)); |
||||
} |
||||
} |
||||
|
||||
static void upbc_Scrape_FileExtensions(upbc_State* s, const upb_FileDef* f) { |
||||
const size_t len = upb_FileDef_TopLevelExtensionCount(f); |
||||
|
||||
for (size_t i = 0; i < len; i++) { |
||||
upbc_Scrape_Extension(s, upb_FileDef_TopLevelExtension(f, i)); |
||||
} |
||||
} |
||||
|
||||
static void upbc_Scrape_FileMessages(upbc_State* s, const upb_FileDef* f) { |
||||
const size_t len = upb_FileDef_TopLevelMessageCount(f); |
||||
|
||||
for (size_t i = 0; i < len; i++) { |
||||
upbc_Scrape_Message(s, upb_FileDef_TopLevelMessage(f, i)); |
||||
} |
||||
} |
||||
|
||||
static void upbc_Scrape_File(upbc_State* s, const upb_FileDef* f) { |
||||
upbc_Scrape_FileEnums(s, f); |
||||
upbc_Scrape_FileExtensions(s, f); |
||||
upbc_Scrape_FileMessages(s, f); |
||||
} |
||||
|
||||
static void upbc_Scrape_Files(upbc_State* s) { |
||||
const google_protobuf_compiler_CodeGeneratorRequest* request = |
||||
upb_CodeGeneratorRequest_request(s->out); |
||||
|
||||
size_t len = 0; |
||||
const google_protobuf_FileDescriptorProto* const* files = |
||||
google_protobuf_compiler_CodeGeneratorRequest_proto_file(request, &len); |
||||
|
||||
for (size_t i = 0; i < len; i++) { |
||||
const upb_FileDef* f = upb_DefPool_AddFile(s->symtab, files[i], s->status); |
||||
if (!f) upbc_Error(s, __func__, "could not add file to def pool"); |
||||
|
||||
upbc_Scrape_File(s, f); |
||||
} |
||||
} |
||||
|
||||
static void upbc_Scrape_NestedEnums(upbc_State* s, const upb_MessageDef* m) { |
||||
const size_t len = upb_MessageDef_NestedEnumCount(m); |
||||
|
||||
for (size_t i = 0; i < len; i++) { |
||||
upbc_Scrape_Enum(s, upb_MessageDef_NestedEnum(m, i)); |
||||
} |
||||
} |
||||
|
||||
static void upbc_Scrape_NestedExtensions(upbc_State* s, |
||||
const upb_MessageDef* m) { |
||||
const size_t len = upb_MessageDef_NestedExtensionCount(m); |
||||
|
||||
for (size_t i = 0; i < len; i++) { |
||||
upbc_Scrape_Extension(s, upb_MessageDef_NestedExtension(m, i)); |
||||
} |
||||
} |
||||
|
||||
static void upbc_Scrape_NestedMessages(upbc_State* s, const upb_MessageDef* m) { |
||||
const size_t len = upb_MessageDef_NestedMessageCount(m); |
||||
|
||||
for (size_t i = 0; i < len; i++) { |
||||
upbc_Scrape_Message(s, upb_MessageDef_NestedMessage(m, i)); |
||||
} |
||||
} |
||||
|
||||
static void upbc_Scrape_MessageSubs(upbc_State* s, |
||||
upb_CodeGeneratorRequest_UpbInfo* info, |
||||
const upb_MessageDef* m) { |
||||
const upb_MiniTableField** fields = |
||||
malloc(upb_MessageDef_FieldCount(m) * sizeof(*fields)); |
||||
const upb_MiniTable* mt = upb_MessageDef_MiniTable(m); |
||||
uint32_t counts = upb_MiniTable_GetSubList(mt, fields); |
||||
uint32_t msg_count = counts >> 16; |
||||
uint32_t enum_count = counts & 0xffff; |
||||
|
||||
for (uint32_t i = 0; i < msg_count; i++) { |
||||
const upb_FieldDef* f = upb_MessageDef_FindFieldByNumber( |
||||
m, upb_MiniTableField_Number(fields[i])); |
||||
if (!f) upbc_Error(s, __func__, "Missing f"); |
||||
const upb_MessageDef* sub = upb_FieldDef_MessageSubDef(f); |
||||
if (!sub) upbc_Error(s, __func__, "Missing sub"); |
||||
upb_StringView name = upbc_State_StrDup(s, upb_MessageDef_FullName(sub)); |
||||
upb_CodeGeneratorRequest_UpbInfo_add_sub_message(info, name, s->arena); |
||||
} |
||||
|
||||
for (uint32_t i = 0; i < enum_count; i++) { |
||||
const upb_FieldDef* f = upb_MessageDef_FindFieldByNumber( |
||||
m, upb_MiniTableField_Number(fields[msg_count + i])); |
||||
if (!f) upbc_Error(s, __func__, "Missing f (2)"); |
||||
const upb_EnumDef* sub = upb_FieldDef_EnumSubDef(f); |
||||
if (!sub) upbc_Error(s, __func__, "Missing sub (2)"); |
||||
upb_StringView name = upbc_State_StrDup(s, upb_EnumDef_FullName(sub)); |
||||
upb_CodeGeneratorRequest_UpbInfo_add_sub_enum(info, name, s->arena); |
||||
} |
||||
|
||||
free(fields); |
||||
} |
||||
|
||||
static void upbc_Scrape_Message(upbc_State* s, const upb_MessageDef* m) { |
||||
upb_StringView desc; |
||||
bool ok = upb_MessageDef_MiniDescriptorEncode(m, s->arena, &desc); |
||||
if (!ok) upbc_Error(s, __func__, "could not encode message"); |
||||
|
||||
upb_CodeGeneratorRequest_UpbInfo* info = |
||||
upb_CodeGeneratorRequest_UpbInfo_new(s->arena); |
||||
if (!info) upbc_Error(s, __func__, "Out of memory"); |
||||
upb_CodeGeneratorRequest_UpbInfo_set_mini_descriptor(info, desc); |
||||
|
||||
upbc_Scrape_MessageSubs(s, info, m); |
||||
|
||||
const upb_StringView key = upbc_State_StrDup(s, upb_MessageDef_FullName(m)); |
||||
ok = upb_CodeGeneratorRequest_upb_info_set(s->out, key, info, s->arena); |
||||
if (!ok) upbc_Error(s, __func__, "could not set mini descriptor in map"); |
||||
|
||||
upbc_Scrape_NestedEnums(s, m); |
||||
upbc_Scrape_NestedExtensions(s, m); |
||||
upbc_Scrape_NestedMessages(s, m); |
||||
} |
||||
|
||||
static upb_CodeGeneratorRequest* upbc_State_MakeCodeGeneratorRequest( |
||||
upbc_State* const s, google_protobuf_compiler_CodeGeneratorRequest* const request) { |
||||
if (UPB_SETJMP(s->jmp)) return NULL; |
||||
upbc_State_Init(s); |
||||
|
||||
upb_CodeGeneratorRequest_set_request(s->out, request); |
||||
upbc_Scrape_Files(s); |
||||
upbc_State_Fini(s); |
||||
return s->out; |
||||
} |
||||
|
||||
upb_CodeGeneratorRequest* upbc_MakeCodeGeneratorRequest( |
||||
google_protobuf_compiler_CodeGeneratorRequest* request, upb_Arena* arena, |
||||
upb_Status* status) { |
||||
upbc_State s = { |
||||
.arena = arena, |
||||
.status = status, |
||||
.symtab = NULL, |
||||
.out = NULL, |
||||
}; |
||||
|
||||
return upbc_State_MakeCodeGeneratorRequest(&s, request); |
||||
} |
@ -1,32 +0,0 @@ |
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2023 Google LLC. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file or at
|
||||
// https://developers.google.com/open-source/licenses/bsd
|
||||
|
||||
#ifndef UPB_GENERATOR_CODE_GENERATOR_REQUEST_H_ |
||||
#define UPB_GENERATOR_CODE_GENERATOR_REQUEST_H_ |
||||
|
||||
#include "upb/mem/arena.h" |
||||
#include "upb/reflection/def.h" |
||||
#include "upb_generator/code_generator_request.upb.h" |
||||
|
||||
// Must be last.
|
||||
#include "upb/port/def.inc" |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
upb_CodeGeneratorRequest* upbc_MakeCodeGeneratorRequest( |
||||
struct google_protobuf_compiler_CodeGeneratorRequest* request, upb_Arena* a, |
||||
upb_Status* s); |
||||
|
||||
#ifdef __cplusplus |
||||
} /* extern "C" */ |
||||
#endif |
||||
|
||||
#include "upb/port/undef.inc" |
||||
|
||||
#endif /* UPB_GENERATOR_CODE_GENERATOR_REQUEST_H_ */ |
@ -1,33 +0,0 @@ |
||||
// Protocol Buffers - Google's data interchange format |
||||
// Copyright 2023 Google LLC. All rights reserved. |
||||
// |
||||
// Use of this source code is governed by a BSD-style |
||||
// license that can be found in the LICENSE file or at |
||||
// https://developers.google.com/open-source/licenses/bsd |
||||
|
||||
syntax = "proto2"; |
||||
|
||||
package upb; |
||||
|
||||
import "google/protobuf/compiler/plugin.proto"; |
||||
|
||||
message CodeGeneratorRequest { |
||||
message UpbInfo { |
||||
optional string mini_descriptor = 1; |
||||
|
||||
// An ordered list of fully qualified sub-message names whose upb_MiniTable |
||||
// should be passed to upb_MiniTable_Link(). |
||||
repeated string sub_message = 3; |
||||
|
||||
// An ordered list of fully qualified sub-enum names whose upb_MiniTableEnum |
||||
// should be passed to upb_MiniTable_Link(). |
||||
repeated string sub_enum = 4; |
||||
} |
||||
|
||||
// The pb sent by protoc to its plugins. |
||||
optional google.protobuf.compiler.CodeGeneratorRequest request = 1; |
||||
|
||||
// upb-specific info for the messages/enums/extensions in the request, keyed |
||||
// by the fully qualified names. |
||||
map<string, UpbInfo> upb_info = 2; |
||||
} |
@ -1,130 +0,0 @@ |
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2023 Google LLC. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file or at
|
||||
// https://developers.google.com/open-source/licenses/bsd
|
||||
|
||||
#include "upb_generator/get_used_fields.h" |
||||
|
||||
#include <stddef.h> |
||||
#include <stdio.h> |
||||
#include <stdlib.h> |
||||
#include <string.h> |
||||
|
||||
#include "google/protobuf/descriptor.upb.h" |
||||
#include "google/protobuf/compiler/plugin.upb.h" |
||||
#include "upb/base/descriptor_constants.h" |
||||
#include "upb/base/string_view.h" |
||||
#include "upb/mem/arena.h" |
||||
#include "upb/message/array.h" |
||||
#include "upb/message/map.h" |
||||
#include "upb/message/message.h" |
||||
#include "upb/mini_table/message.h" |
||||
#include "upb/reflection/def.h" |
||||
#include "upb/reflection/message.h" |
||||
#include "upb/wire/decode.h" |
||||
|
||||
// Must be last.
|
||||
#include "upb/port/def.inc" |
||||
|
||||
#define upbdev_Err(...) \ |
||||
{ \
|
||||
fprintf(stderr, __VA_ARGS__); \
|
||||
exit(1); \
|
||||
} |
||||
|
||||
typedef struct { |
||||
char* buf; |
||||
size_t size; |
||||
size_t capacity; |
||||
upb_Arena* arena; |
||||
} upbdev_StringBuf; |
||||
|
||||
void upbdev_StringBuf_Add(upbdev_StringBuf* buf, const char* sym) { |
||||
size_t len = strlen(sym); |
||||
size_t need = buf->size + len + (buf->size != 0); |
||||
if (need > buf->capacity) { |
||||
size_t new_cap = UPB_MAX(buf->capacity, 32); |
||||
while (need > new_cap) new_cap *= 2; |
||||
buf->buf = upb_Arena_Realloc(buf->arena, buf->buf, buf->capacity, new_cap); |
||||
buf->capacity = new_cap; |
||||
} |
||||
if (buf->size != 0) { |
||||
buf->buf[buf->size++] = '\n'; // Separator
|
||||
} |
||||
memcpy(buf->buf + buf->size, sym, len); |
||||
buf->size = need; |
||||
} |
||||
|
||||
void upbdev_VisitMessage(upbdev_StringBuf* buf, const upb_Message* msg, |
||||
const upb_MessageDef* m) { |
||||
size_t iter = kUpb_Message_Begin; |
||||
const upb_FieldDef* f; |
||||
upb_MessageValue val; |
||||
while (upb_Message_Next(msg, m, NULL, &f, &val, &iter)) { |
||||
// This could be a duplicate, but we don't worry about it; we'll dedupe
|
||||
// one level up.
|
||||
upbdev_StringBuf_Add(buf, upb_FieldDef_FullName(f)); |
||||
|
||||
if (upb_FieldDef_CType(f) != kUpb_CType_Message) continue; |
||||
const upb_MessageDef* sub = upb_FieldDef_MessageSubDef(f); |
||||
|
||||
if (upb_FieldDef_IsMap(f)) { |
||||
const upb_Map* map = val.map_val; |
||||
size_t iter = kUpb_Map_Begin; |
||||
upb_MessageValue map_key, map_val; |
||||
while (upb_Map_Next(map, &map_key, &map_val, &iter)) { |
||||
upbdev_VisitMessage(buf, map_val.msg_val, sub); |
||||
} |
||||
} else if (upb_FieldDef_IsRepeated(f)) { |
||||
const upb_Array* arr = val.array_val; |
||||
size_t n = upb_Array_Size(arr); |
||||
for (size_t i = 0; i < n; i++) { |
||||
upb_MessageValue val = upb_Array_Get(arr, i); |
||||
upbdev_VisitMessage(buf, val.msg_val, sub); |
||||
} |
||||
} else { |
||||
upbdev_VisitMessage(buf, val.msg_val, sub); |
||||
} |
||||
} |
||||
} |
||||
|
||||
upb_StringView upbdev_GetUsedFields(const char* request, size_t request_size, |
||||
const char* payload, size_t payload_size, |
||||
const char* message_name, |
||||
upb_Arena* arena) { |
||||
upb_Arena* tmp_arena = upb_Arena_New(); |
||||
google_protobuf_compiler_CodeGeneratorRequest* request_proto = |
||||
google_protobuf_compiler_CodeGeneratorRequest_parse(request, request_size, |
||||
tmp_arena); |
||||
if (!request_proto) upbdev_Err("Couldn't parse request proto\n"); |
||||
|
||||
size_t len; |
||||
const google_protobuf_FileDescriptorProto* const* files = |
||||
google_protobuf_compiler_CodeGeneratorRequest_proto_file(request_proto, &len); |
||||
|
||||
upb_DefPool* pool = upb_DefPool_New(); |
||||
for (size_t i = 0; i < len; i++) { |
||||
const upb_FileDef* f = upb_DefPool_AddFile(pool, files[i], NULL); |
||||
if (!f) upbdev_Err("could not add file to def pool\n"); |
||||
} |
||||
|
||||
const upb_MessageDef* m = upb_DefPool_FindMessageByName(pool, message_name); |
||||
if (!m) upbdev_Err("Couldn't find message name\n"); |
||||
|
||||
const upb_MiniTable* mt = upb_MessageDef_MiniTable(m); |
||||
upb_Message* msg = upb_Message_New(mt, tmp_arena); |
||||
upb_DecodeStatus st = |
||||
upb_Decode(payload, payload_size, msg, mt, NULL, 0, tmp_arena); |
||||
if (st != kUpb_DecodeStatus_Ok) upbdev_Err("Error parsing payload: %d\n", st); |
||||
|
||||
upbdev_StringBuf buf = { |
||||
.buf = NULL, |
||||
.size = 0, |
||||
.capacity = 0, |
||||
.arena = arena, |
||||
}; |
||||
upbdev_VisitMessage(&buf, msg, m); |
||||
return upb_StringView_FromDataAndSize(buf.buf, buf.size); |
||||
} |
@ -1,34 +0,0 @@ |
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2023 Google LLC. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file or at
|
||||
// https://developers.google.com/open-source/licenses/bsd
|
||||
|
||||
#ifndef UPB_GENERATOR_GET_USED_FIELDS |
||||
#define UPB_GENERATOR_GET_USED_FIELDS |
||||
|
||||
#include "upb/base/status.h" |
||||
#include "upb/base/string_view.h" |
||||
#include "upb/mem/arena.h" |
||||
|
||||
// Must be last.
|
||||
#include "upb/port/def.inc" |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
// Consume |buf|, deserialize it to a Code_Generator_Request proto, then
|
||||
// upb_Code_Generator_Request, and return it as a JSON-encoded string.
|
||||
UPB_API upb_StringView upbdev_GetUsedFields( |
||||
const char* request, size_t request_size, const char* payload, |
||||
size_t payload_size, const char* message_name, upb_Arena* arena); |
||||
|
||||
#ifdef __cplusplus |
||||
} /* extern "C" */ |
||||
#endif |
||||
|
||||
#include "upb/port/undef.inc" |
||||
|
||||
#endif // UPB_GENERATOR_GET_USED_FIELDS
|
@ -1,11 +0,0 @@ |
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2023 Google LLC. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file or at
|
||||
// https://developers.google.com/open-source/licenses/bsd
|
||||
|
||||
// These headers form a spanning tree for the upbc defs needed by FFI layers.
|
||||
|
||||
#include "upb_generator/get_used_fields.h" |
||||
#include "upb_generator/upbdev.h" |
@ -1,118 +0,0 @@ |
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2023 Google LLC. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file or at
|
||||
// https://developers.google.com/open-source/licenses/bsd
|
||||
|
||||
#include "upb_generator/upbdev.h" |
||||
|
||||
#ifdef _WIN32 |
||||
#ifndef WIN32_LEAN_AND_MEAN |
||||
#define WIN32_LEAN_AND_MEAN |
||||
#endif |
||||
#include <windows.h> |
||||
#else // _WIN32
|
||||
#include <unistd.h> |
||||
#endif // !_WIN32
|
||||
|
||||
#include "google/protobuf/compiler/plugin.upb.h" |
||||
#include "google/protobuf/compiler/plugin.upbdefs.h" |
||||
#include "upb/base/status.h" |
||||
#include "upb/base/upcast.h" |
||||
#include "upb/json/decode.h" |
||||
#include "upb/json/encode.h" |
||||
#include "upb/mem/arena.h" |
||||
#include "upb_generator/code_generator_request.h" |
||||
#include "upb_generator/code_generator_request.upb.h" |
||||
#include "upb_generator/code_generator_request.upbdefs.h" |
||||
|
||||
static google_protobuf_compiler_CodeGeneratorResponse* upbc_JsonDecode( |
||||
const char* data, size_t size, upb_Arena* arena, upb_Status* status) { |
||||
google_protobuf_compiler_CodeGeneratorResponse* response = |
||||
google_protobuf_compiler_CodeGeneratorResponse_new(arena); |
||||
|
||||
upb_DefPool* s = upb_DefPool_New(); |
||||
const upb_MessageDef* m = google_protobuf_compiler_CodeGeneratorResponse_getmsgdef(s); |
||||
|
||||
(void)upb_JsonDecode(data, size, UPB_UPCAST(response), m, s, 0, arena, |
||||
status); |
||||
if (!upb_Status_IsOk(status)) return NULL; |
||||
|
||||
upb_DefPool_Free(s); |
||||
|
||||
return response; |
||||
} |
||||
|
||||
static upb_StringView upbc_JsonEncode(const upb_CodeGeneratorRequest* request, |
||||
upb_Arena* arena, upb_Status* status) { |
||||
upb_StringView out = {.data = NULL, .size = 0}; |
||||
|
||||
upb_DefPool* s = upb_DefPool_New(); |
||||
const upb_MessageDef* m = upb_CodeGeneratorRequest_getmsgdef(s); |
||||
const int options = upb_JsonEncode_FormatEnumsAsIntegers; |
||||
|
||||
out.size = |
||||
upb_JsonEncode(UPB_UPCAST(request), m, s, options, NULL, 0, status); |
||||
if (!upb_Status_IsOk(status)) goto done; |
||||
|
||||
char* data = (char*)upb_Arena_Malloc(arena, out.size + 1); |
||||
|
||||
(void)upb_JsonEncode(UPB_UPCAST(request), m, s, options, data, out.size + 1, |
||||
status); |
||||
if (!upb_Status_IsOk(status)) goto done; |
||||
|
||||
out.data = (const char*)data; |
||||
|
||||
done: |
||||
upb_DefPool_Free(s); |
||||
return out; |
||||
} |
||||
|
||||
upb_StringView upbdev_ProcessInput(const char* buf, size_t size, |
||||
upb_Arena* arena, upb_Status* status) { |
||||
upb_StringView out = {.data = NULL, .size = 0}; |
||||
|
||||
google_protobuf_compiler_CodeGeneratorRequest* inner_request = |
||||
google_protobuf_compiler_CodeGeneratorRequest_parse(buf, size, arena); |
||||
|
||||
const upb_CodeGeneratorRequest* outer_request = |
||||
upbc_MakeCodeGeneratorRequest(inner_request, arena, status); |
||||
if (!upb_Status_IsOk(status)) return out; |
||||
|
||||
return upbc_JsonEncode(outer_request, arena, status); |
||||
} |
||||
|
||||
static upb_StringView upbdev_ProcessOutput(const char* buf, size_t size, |
||||
upb_Arena* arena, |
||||
upb_Status* status) { |
||||
upb_StringView out = {.data = NULL, .size = 0}; |
||||
|
||||
const google_protobuf_compiler_CodeGeneratorResponse* response = |
||||
upbc_JsonDecode(buf, size, arena, status); |
||||
if (!upb_Status_IsOk(status)) return out; |
||||
|
||||
out.data = google_protobuf_compiler_CodeGeneratorResponse_serialize(response, arena, |
||||
&out.size); |
||||
return out; |
||||
} |
||||
|
||||
void upbdev_ProcessStdout(const char* buf, size_t size, upb_Arena* arena, |
||||
upb_Status* status) { |
||||
const upb_StringView sv = upbdev_ProcessOutput(buf, size, arena, status); |
||||
if (!upb_Status_IsOk(status)) return; |
||||
|
||||
const char* ptr = sv.data; |
||||
size_t len = sv.size; |
||||
while (len) { |
||||
int n = write(1, ptr, len); |
||||
if (n > 0) { |
||||
ptr += n; |
||||
len -= n; |
||||
} |
||||
} |
||||
} |
||||
|
||||
upb_Arena* upbdev_Arena_New(void) { return upb_Arena_New(); } |
||||
|
||||
void upbdev_Status_Clear(upb_Status* status) { upb_Status_Clear(status); } |
@ -1,43 +0,0 @@ |
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2023 Google LLC. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file or at
|
||||
// https://developers.google.com/open-source/licenses/bsd
|
||||
|
||||
#ifndef UPB_GENERATOR_UPBDEV_H_ |
||||
#define UPB_GENERATOR_UPBDEV_H_ |
||||
|
||||
#include "upb/base/status.h" |
||||
#include "upb/base/string_view.h" |
||||
#include "upb/mem/arena.h" |
||||
|
||||
// Must be last.
|
||||
#include "upb/port/def.inc" |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
// Consume |buf|, deserialize it to a Code_Generator_Request proto, construct a
|
||||
// upb_Code_Generator_Request, and return it as a JSON-encoded string.
|
||||
UPB_API upb_StringView upbdev_ProcessInput(const char* buf, size_t size, |
||||
upb_Arena* arena, |
||||
upb_Status* status); |
||||
|
||||
// Decode |buf| from JSON, serialize to wire format, and write it to stdout.
|
||||
UPB_API void upbdev_ProcessStdout(const char* buf, size_t size, |
||||
upb_Arena* arena, upb_Status* status); |
||||
|
||||
// The following wrappers allow the protoc plugins to call the above functions
|
||||
// without pulling in the entire pb_runtime library.
|
||||
UPB_API upb_Arena* upbdev_Arena_New(void); |
||||
UPB_API void upbdev_Status_Clear(upb_Status* status); |
||||
|
||||
#ifdef __cplusplus |
||||
} /* extern "C" */ |
||||
#endif |
||||
|
||||
#include "upb/port/undef.inc" |
||||
|
||||
#endif // UPB_GENERATOR_UPBDEV_H_
|
Loading…
Reference in new issue