Protocol Buffers - Google's data interchange format (grpc依赖) https://developers.google.com/protocol-buffers/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

123 lines
3.8 KiB

/*
* upb - a minimalist implementation of protocol buffers.
*
* Copyright (c) 2011-2012 Google Inc. See LICENSE for details.
*
* A test that verifies that our results are identical to proto2 for a
* given proto type and input protobuf.
*/
#define __STDC_LIMIT_MACROS // So we get UINT32_MAX
#include <assert.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/wire_format_lite.h>
#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include "benchmarks/google_messages.pb.h"
#include "upb/def.hpp"
#include "upb/handlers.hpp"
#include "upb/msg.hpp"
#include "upb/pb/decoder.hpp"
#include "upb/pb/glue.h"
#include "upb/pb/varint.h"
#include "upb/proto2_bridge.hpp"
#include "upb_test.h"
void compare_metadata(const google::protobuf::Descriptor* d,
const upb::MessageDef *upb_md) {
ASSERT(d->field_count() == upb_md->field_count());
for (upb::MessageDef::ConstIterator i(upb_md); !i.Done(); i.Next()) {
const upb::FieldDef* upb_f = i.field();
const google::protobuf::FieldDescriptor *proto2_f =
d->FindFieldByNumber(upb_f->number());
ASSERT(upb_f);
ASSERT(proto2_f);
ASSERT(upb_f->number() == proto2_f->number());
ASSERT(std::string(upb_f->name()) == proto2_f->name());
ASSERT(upb_f->type() == static_cast<upb::FieldType>(proto2_f->type()));
ASSERT(upb_f->IsSequence() == proto2_f->is_repeated());
}
}
void parse_and_compare(MESSAGE_CIDENT *msg1, MESSAGE_CIDENT *msg2,
const upb::MessageDef *upb_md,
const char *str, size_t len, bool allow_jit) {
// Parse to both proto2 and upb.
ASSERT(msg1->ParseFromArray(str, len));
upb::Handlers* handlers = upb::Handlers::New();
upb::RegisterWriteHandlers(handlers, upb_md);
upb::DecoderPlan* plan = upb::DecoderPlan::New(handlers, allow_jit);
upb::StringSource src(str, len);
upb::Decoder decoder;
decoder.ResetPlan(plan, 0);
decoder.ResetInput(src.AllBytes(), msg2);
msg2->Clear();
ASSERT(decoder.Decode() == UPB_OK);
plan->Unref();
handlers->Unref();
// Would like to just compare the message objects themselves, but
// unfortunately MessageDifferencer is not part of the open-source release of
// proto2, so we compare their serialized strings, which we expect will be
// equivalent.
std::string str1;
std::string str2;
msg1->SerializeToString(&str1);
msg2->SerializeToString(&str2);
ASSERT(str1 == str2);
ASSERT(std::string(str, len) == str2);
}
void test_zig_zag() {
for (uint64_t num = 5; num * 1.5 > num; num *= 1.5) {
ASSERT(upb_zzenc_64(num) ==
google::protobuf::internal::WireFormatLite::ZigZagEncode64(num));
if (num < UINT32_MAX) {
ASSERT(upb_zzenc_32(num) ==
google::protobuf::internal::WireFormatLite::ZigZagEncode32(num));
}
}
}
int main(int argc, char *argv[])
{
if (argc < 2) {
fprintf(stderr, "Usage: test_vs_proto2 <message file>\n");
return 1;
}
const char *message_file = argv[1];
// Read the message data itself.
size_t len;
const char *str = upb_readfile(message_file, &len);
if(str == NULL) {
fprintf(stderr, "Error reading %s\n", message_file);
return 1;
}
MESSAGE_CIDENT msg1;
MESSAGE_CIDENT msg2;
const upb::MessageDef* m = upb::proto2_bridge::NewFinalMessageDef(msg1, &m);
compare_metadata(msg1.GetDescriptor(), m);
// Run twice to test proper object reuse.
parse_and_compare(&msg1, &msg2, m, str, len, true);
parse_and_compare(&msg1, &msg2, m, str, len, false);
parse_and_compare(&msg1, &msg2, m, str, len, true);
parse_and_compare(&msg1, &msg2, m, str, len, false);
printf("All tests passed, %d assertions.\n", num_assertions);
m->Unref(&m);
free((void*)str);
test_zig_zag();
google::protobuf::ShutdownProtobufLibrary();
return 0;
}