-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmetadata_builder.cpp
111 lines (95 loc) · 3.97 KB
/
metadata_builder.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0
#include <fstream>
#include <string>
#include "clr_helpers.h"
#include "logger.h"
#include "macros.h"
#include "metadata_builder.h"
namespace trace
{
HRESULT MetadataBuilder::EmitAssemblyRef(const trace::AssemblyReference& assembly_ref) const
{
ASSEMBLYMETADATA assembly_metadata{};
assembly_metadata.usMajorVersion = assembly_ref.version.major;
assembly_metadata.usMinorVersion = assembly_ref.version.minor;
assembly_metadata.usBuildNumber = assembly_ref.version.build;
assembly_metadata.usRevisionNumber = assembly_ref.version.revision;
if (assembly_ref.locale == WStr("neutral"))
{
assembly_metadata.szLocale = nullptr;
assembly_metadata.cbLocale = 0;
}
else
{
assembly_metadata.szLocale = const_cast<WCHAR*>(assembly_ref.locale.c_str());
assembly_metadata.cbLocale = (DWORD)(assembly_ref.locale.size());
}
DWORD public_key_size = 8;
if (assembly_ref.public_key == trace::PublicKey())
{
public_key_size = 0;
}
mdAssemblyRef assembly_ref_out;
const HRESULT hr = assembly_emit_->DefineAssemblyRef(&assembly_ref.public_key.data[0], public_key_size,
assembly_ref.name.c_str(), &assembly_metadata,
// hash blob
nullptr,
// cb of hash blob
0,
// flags
0, &assembly_ref_out);
if (FAILED(hr))
{
Logger::Warn("DefineAssemblyRef failed");
}
return S_OK;
}
HRESULT MetadataBuilder::FindIntegrationTypeRef(const IntegrationDefinition& integration_definition,
mdTypeRef& type_ref_out) const
{
const auto& cache_key = integration_definition.integration_type.get_cache_key();
mdTypeRef type_ref = mdTypeRefNil;
if (metadata_.TryGetIntegrationTypeRef(cache_key, type_ref))
{
// this type was already resolved
type_ref_out = type_ref;
return S_OK;
}
HRESULT hr;
type_ref = mdTypeRefNil;
if (metadata_.assemblyName == integration_definition.integration_type.assembly.name)
{
// type is defined in this assembly
hr = metadata_emit_->DefineTypeRefByName(module_, integration_definition.integration_type.name.c_str(),
&type_ref);
}
else
{
// type is defined in another assembly,
// find a reference to the assembly where type lives
const auto assembly_ref =
FindAssemblyRef(assembly_import_, integration_definition.integration_type.assembly.name);
if (assembly_ref == mdAssemblyRefNil)
{
// TODO: emit assembly reference if not found?
Logger::Warn("Assembly reference for", integration_definition.integration_type.assembly.name, " not found");
return E_FAIL;
}
// search for an existing reference to the type
hr = metadata_import_->FindTypeRef(assembly_ref, integration_definition.integration_type.name.c_str(),
&type_ref);
if (hr == HRESULT(0x80131130) /* record not found on lookup */)
{
// if typeRef not found, create a new one by emitting a metadata token
hr = metadata_emit_->DefineTypeRefByName(assembly_ref, integration_definition.integration_type.name.c_str(),
&type_ref);
}
}
RETURN_IF_FAILED(hr);
// cache the typeRef in case we need it again
metadata_.SetIntegrationTypeRef(cache_key, type_ref);
type_ref_out = type_ref;
return S_OK;
}
} // namespace trace