dynamic-test.c++ 15.8 KB
Newer Older
Kenton Varda's avatar
Kenton Varda committed
1 2
// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors
// Licensed under the MIT License:
3
//
Kenton Varda's avatar
Kenton Varda committed
4 5 6 7 8 9
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
10
//
Kenton Varda's avatar
Kenton Varda committed
11 12
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
13
//
Kenton Varda's avatar
Kenton Varda committed
14 15 16 17 18 19 20
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
21 22 23

#include "dynamic.h"
#include "message.h"
Kenton Varda's avatar
Kenton Varda committed
24
#include <kj/debug.h>
25
#include <kj/compat/gtest.h>
26 27
#include "test-util.h"

28
namespace capnp {
29
namespace _ {  // private
30 31
namespace {

Kenton Varda's avatar
Kenton Varda committed
32 33
template <typename Element, typename T>
void checkList(T reader, std::initializer_list<ReaderFor<Element>> expected) {
34
  auto list = reader.template as<DynamicList>();
Kenton Varda's avatar
Kenton Varda committed
35 36
  ASSERT_EQ(expected.size(), list.size());
  for (uint i = 0; i < expected.size(); i++) {
37
    EXPECT_EQ(expected.begin()[i], list[i].template as<Element>());
Kenton Varda's avatar
Kenton Varda committed
38 39
  }

40
  auto typed = reader.template as<List<Element>>();
Kenton Varda's avatar
Kenton Varda committed
41 42
  ASSERT_EQ(expected.size(), typed.size());
  for (uint i = 0; i < expected.size(); i++) {
43
    EXPECT_EQ(expected.begin()[i], typed[i]);
Kenton Varda's avatar
Kenton Varda committed
44 45 46 47 48 49 50
  }
}

TEST(DynamicApi, Build) {
  MallocMessageBuilder builder;
  auto root = builder.initRoot<DynamicStruct>(Schema::from<TestAllTypes>());

51
  initDynamicTestMessage(root);
Kenton Varda's avatar
Kenton Varda committed
52 53
  checkTestMessage(root.asReader().as<TestAllTypes>());

54 55
  checkDynamicTestMessage(root.asReader());
  checkDynamicTestMessage(root);
Kenton Varda's avatar
Kenton Varda committed
56 57 58
}

TEST(DynamicApi, Read) {
59 60 61
  MallocMessageBuilder builder;
  auto root = builder.initRoot<TestAllTypes>();

Kenton Varda's avatar
Kenton Varda committed
62 63
  initTestMessage(root);

64 65 66
  checkDynamicTestMessage(toDynamic(root.asReader()));
  checkDynamicTestMessage(toDynamic(root).asReader());
  checkDynamicTestMessage(toDynamic(root));
Kenton Varda's avatar
Kenton Varda committed
67 68 69 70
}

TEST(DynamicApi, Defaults) {
  AlignedData<1> nullRoot = {{0, 0, 0, 0, 0, 0, 0, 0}};
71 72
  kj::ArrayPtr<const word> segments[1] = {kj::arrayPtr(nullRoot.words, 1)};
  SegmentArrayMessageReader reader(kj::arrayPtr(segments, 1));
Kenton Varda's avatar
Kenton Varda committed
73
  auto root = reader.getRoot<DynamicStruct>(Schema::from<TestDefaults>());
74
  checkDynamicTestMessage(root);
Kenton Varda's avatar
Kenton Varda committed
75 76 77 78 79 80 81
}

TEST(DynamicApi, DefaultsBuilder) {
  MallocMessageBuilder builder;
  auto root = builder.initRoot<DynamicStruct>(Schema::from<TestDefaults>());

  checkTestMessage(root.asReader().as<TestDefaults>());
82
  checkDynamicTestMessage(root.asReader());
Kenton Varda's avatar
Kenton Varda committed
83 84

  // This will initialize the whole message, replacing null pointers with copies of defaults.
85
  checkDynamicTestMessage(root);
Kenton Varda's avatar
Kenton Varda committed
86 87 88

  // Check again now that the message is initialized.
  checkTestMessage(root.asReader().as<TestDefaults>());
89 90
  checkDynamicTestMessage(root.asReader());
  checkDynamicTestMessage(root);
Kenton Varda's avatar
Kenton Varda committed
91 92 93 94 95 96
}

TEST(DynamicApi, Zero) {
  MallocMessageBuilder builder;
  auto root = builder.initRoot<DynamicStruct>(Schema::from<TestAllTypes>());

97
  checkDynamicTestMessageAllZero(root.asReader());
Kenton Varda's avatar
Kenton Varda committed
98
  checkTestMessageAllZero(root.asReader().as<TestAllTypes>());
99
  checkDynamicTestMessageAllZero(root);
Kenton Varda's avatar
Kenton Varda committed
100 101 102 103 104 105 106
  checkTestMessageAllZero(root.asReader().as<TestAllTypes>());
}

TEST(DynamicApi, ListListsBuild) {
  MallocMessageBuilder builder;
  auto root = builder.initRoot<DynamicStruct>(Schema::from<TestListDefaults>());

107
  initDynamicTestLists(root);
Kenton Varda's avatar
Kenton Varda committed
108 109
  checkTestMessage(root.asReader().as<TestListDefaults>());

110 111
  checkDynamicTestLists(root.asReader());
  checkDynamicTestLists(root);
Kenton Varda's avatar
Kenton Varda committed
112 113 114 115 116 117 118 119
}

TEST(DynamicApi, ListListsRead) {
  MallocMessageBuilder builder;
  auto root = builder.initRoot<TestListDefaults>();

  initTestMessage(root);

120 121 122
  checkDynamicTestLists(toDynamic(root.asReader()));
  checkDynamicTestLists(toDynamic(root).asReader());
  checkDynamicTestLists(toDynamic(root));
Kenton Varda's avatar
Kenton Varda committed
123 124
}

125
TEST(DynamicApi, AnyPointers) {
Kenton Varda's avatar
Kenton Varda committed
126
  MallocMessageBuilder builder;
127
  auto root = builder.getRoot<test::TestAnyPointer>();
Kenton Varda's avatar
Kenton Varda committed
128

129 130 131
  initDynamicTestMessage(
      root.getAnyPointerField().initAs<DynamicStruct>(Schema::from<TestAllTypes>()));
  checkTestMessage(root.asReader().getAnyPointerField().getAs<TestAllTypes>());
Kenton Varda's avatar
Kenton Varda committed
132

133
  checkDynamicTestMessage(
134 135 136
      root.asReader().getAnyPointerField().getAs<DynamicStruct>(Schema::from<TestAllTypes>()));
  checkDynamicTestMessage(
      root.getAnyPointerField().getAs<DynamicStruct>(Schema::from<TestAllTypes>()));
Kenton Varda's avatar
Kenton Varda committed
137 138 139

  {
    {
140
      auto list = root.getAnyPointerField().initAs<DynamicList>(Schema::from<List<uint32_t>>(), 4);
Kenton Varda's avatar
Kenton Varda committed
141 142 143 144 145 146 147
      list.set(0, 123);
      list.set(1, 456);
      list.set(2, 789);
      list.set(3, 123456789);
    }

    {
148
      auto list = root.asReader().getAnyPointerField().getAs<List<uint32_t>>();
Kenton Varda's avatar
Kenton Varda committed
149 150 151 152 153 154 155
      ASSERT_EQ(4u, list.size());
      EXPECT_EQ(123u, list[0]);
      EXPECT_EQ(456u, list[1]);
      EXPECT_EQ(789u, list[2]);
      EXPECT_EQ(123456789u, list[3]);
    }

156
    checkList<uint32_t>(root.asReader().getAnyPointerField().getAs<DynamicList>(
157
        Schema::from<List<uint32_t>>()), {123u, 456u, 789u, 123456789u});
158
    checkList<uint32_t>(root.getAnyPointerField().getAs<DynamicList>(
159
        Schema::from<List<uint32_t>>()), {123u, 456u, 789u, 123456789u});
Kenton Varda's avatar
Kenton Varda committed
160 161 162
  }
}

163
TEST(DynamicApi, DynamicAnyPointers) {
Kenton Varda's avatar
Kenton Varda committed
164
  MallocMessageBuilder builder;
165
  auto root = builder.getRoot<DynamicStruct>(Schema::from<test::TestAnyPointer>());
Kenton Varda's avatar
Kenton Varda committed
166

167
  initDynamicTestMessage(
168
      root.get("anyPointerField").as<AnyPointer>()
169
          .initAs<DynamicStruct>(Schema::from<TestAllTypes>()));
170 171
  checkTestMessage(
      root.asReader().as<test::TestAnyPointer>().getAnyPointerField().getAs<TestAllTypes>());
Kenton Varda's avatar
Kenton Varda committed
172

173
  checkDynamicTestMessage(
174
      root.asReader().get("anyPointerField").as<AnyPointer>()
175
          .getAs<DynamicStruct>(Schema::from<TestAllTypes>()));
176
  checkDynamicTestMessage(
177
      root.asReader().get("anyPointerField").as<AnyPointer>()
178
          .getAs<DynamicStruct>(Schema::from<TestAllTypes>()));
179
  checkDynamicTestMessage(
180
      root.get("anyPointerField").as<AnyPointer>().asReader()
181
          .getAs<DynamicStruct>(Schema::from<TestAllTypes>()));
182
  checkDynamicTestMessage(
183
      root.get("anyPointerField").as<AnyPointer>()
184
          .getAs<DynamicStruct>(Schema::from<TestAllTypes>()));
Kenton Varda's avatar
Kenton Varda committed
185 186 187

  {
    {
188
      auto list = root.init("anyPointerField").as<AnyPointer>()
189
                      .initAs<DynamicList>(Schema::from<List<uint32_t>>(), 4);
Kenton Varda's avatar
Kenton Varda committed
190 191 192 193 194 195 196
      list.set(0, 123);
      list.set(1, 456);
      list.set(2, 789);
      list.set(3, 123456789);
    }

    {
197 198
      auto list = root.asReader().as<test::TestAnyPointer>()
          .getAnyPointerField().getAs<List<uint32_t>>();
Kenton Varda's avatar
Kenton Varda committed
199 200 201 202 203 204 205 206
      ASSERT_EQ(4u, list.size());
      EXPECT_EQ(123u, list[0]);
      EXPECT_EQ(456u, list[1]);
      EXPECT_EQ(789u, list[2]);
      EXPECT_EQ(123456789u, list[3]);
    }

    checkList<uint32_t>(
207
        root.asReader().get("anyPointerField").as<AnyPointer>()
208
            .getAs<DynamicList>(Schema::from<List<uint32_t>>()),
Kenton Varda's avatar
Kenton Varda committed
209 210
        {123u, 456u, 789u, 123456789u});
    checkList<uint32_t>(
211
        root.asReader().get("anyPointerField").as<AnyPointer>()
212
            .getAs<DynamicList>(Schema::from<List<uint32_t>>()),
213 214
        {123u, 456u, 789u, 123456789u});
    checkList<uint32_t>(
215
        root.get("anyPointerField").as<AnyPointer>().asReader()
216
            .getAs<DynamicList>(Schema::from<List<uint32_t>>()),
Kenton Varda's avatar
Kenton Varda committed
217 218
        {123u, 456u, 789u, 123456789u});
    checkList<uint32_t>(
219
        root.get("anyPointerField").as<AnyPointer>()
220
            .getAs<DynamicList>(Schema::from<List<uint32_t>>()),
Kenton Varda's avatar
Kenton Varda committed
221 222 223 224
        {123u, 456u, 789u, 123456789u});
  }
}

225 226 227 228 229 230 231 232 233
TEST(DynamicApi, DynamicAnyStructs) {
  MallocMessageBuilder builder;
  auto root = builder.initRoot<DynamicStruct>(Schema::from<TestAllTypes>());

  root.as<AnyStruct>().as<TestAllTypes>().setInt8Field(123);
  EXPECT_EQ(root.get("int8Field").as<int8_t>(), 123);
  EXPECT_EQ(root.asReader().as<AnyStruct>().as<TestAllTypes>().getInt8Field(), 123);
}

234 235 236 237
#define EXPECT_MAYBE_EQ(name, exp, expected, actual) \
  KJ_IF_MAYBE(name, exp) { \
    EXPECT_EQ(expected, actual); \
  } else { \
238
    KJ_FAIL_EXPECT("Maybe was empty."); \
239 240
  }

Kenton Varda's avatar
Kenton Varda committed
241 242 243 244 245 246 247 248 249 250 251 252
TEST(DynamicApi, UnionsRead) {
  MallocMessageBuilder builder;
  auto root = builder.initRoot<TestUnion>();

  root.getUnion0().setU0f1s32(1234567);
  root.getUnion1().setU1f1sp("foo");
  root.getUnion2().setU2f0s1(true);
  root.getUnion3().setU3f0s64(1234567890123456789ll);

  {
    auto dynamic = toDynamic(root.asReader());
    {
253
      auto u = dynamic.get("union0").as<DynamicStruct>();
254
      EXPECT_MAYBE_EQ(w, u.which(), "u0f1s32", w->getProto().getName());
255
      EXPECT_EQ(1234567, u.get("u0f1s32").as<int32_t>());
Kenton Varda's avatar
Kenton Varda committed
256 257
    }
    {
258
      auto u = dynamic.get("union1").as<DynamicStruct>();
259
      EXPECT_MAYBE_EQ(w, u.which(), "u1f1sp", w->getProto().getName());
260
      EXPECT_EQ("foo", u.get("u1f1sp").as<Text>());
Kenton Varda's avatar
Kenton Varda committed
261 262
    }
    {
263
      auto u = dynamic.get("union2").as<DynamicStruct>();
264
      EXPECT_MAYBE_EQ(w, u.which(), "u2f0s1", w->getProto().getName());
265
      EXPECT_TRUE(u.get("u2f0s1").as<bool>());
Kenton Varda's avatar
Kenton Varda committed
266 267
    }
    {
268
      auto u = dynamic.get("union3").as<DynamicStruct>();
269
      EXPECT_MAYBE_EQ(w, u.which(), "u3f0s64", w->getProto().getName());
270
      EXPECT_EQ(1234567890123456789ll, u.get("u3f0s64").as<int64_t>());
Kenton Varda's avatar
Kenton Varda committed
271 272 273 274 275 276 277
    }
  }

  {
    // Again as a builder.
    auto dynamic = toDynamic(root);
    {
278
      auto u = dynamic.get("union0").as<DynamicStruct>();
279
      EXPECT_MAYBE_EQ(w, u.which(), "u0f1s32", w->getProto().getName());
280
      EXPECT_EQ(1234567, u.get("u0f1s32").as<int32_t>());
Kenton Varda's avatar
Kenton Varda committed
281 282
    }
    {
283
      auto u = dynamic.get("union1").as<DynamicStruct>();
284
      EXPECT_MAYBE_EQ(w, u.which(), "u1f1sp", w->getProto().getName());
285
      EXPECT_EQ("foo", u.get("u1f1sp").as<Text>());
Kenton Varda's avatar
Kenton Varda committed
286 287
    }
    {
288
      auto u = dynamic.get("union2").as<DynamicStruct>();
289
      EXPECT_MAYBE_EQ(w, u.which(), "u2f0s1", w->getProto().getName());
290
      EXPECT_TRUE(u.get("u2f0s1").as<bool>());
Kenton Varda's avatar
Kenton Varda committed
291 292
    }
    {
293
      auto u = dynamic.get("union3").as<DynamicStruct>();
294
      EXPECT_MAYBE_EQ(w, u.which(), "u3f0s64", w->getProto().getName());
295
      EXPECT_EQ(1234567890123456789ll, u.get("u3f0s64").as<int64_t>());
Kenton Varda's avatar
Kenton Varda committed
296 297 298 299 300 301 302 303
    }
  }
}

TEST(DynamicApi, UnionsWrite) {
  MallocMessageBuilder builder;
  auto root = builder.initRoot<DynamicStruct>(Schema::from<TestUnion>());

304 305 306 307
  root.get("union0").as<DynamicStruct>().set("u0f1s32", 1234567);
  root.get("union1").as<DynamicStruct>().set("u1f1sp", "foo");
  root.get("union2").as<DynamicStruct>().set("u2f0s1", true);
  root.get("union3").as<DynamicStruct>().set("u3f0s64", 1234567890123456789ll);
Kenton Varda's avatar
Kenton Varda committed
308 309 310 311 312 313 314 315 316 317 318 319 320

  auto reader = root.asReader().as<TestUnion>();
  ASSERT_EQ(TestUnion::Union0::U0F1S32, reader.getUnion0().which());
  EXPECT_EQ(1234567, reader.getUnion0().getU0f1s32());

  ASSERT_EQ(TestUnion::Union1::U1F1SP, reader.getUnion1().which());
  EXPECT_EQ("foo", reader.getUnion1().getU1f1sp());

  ASSERT_EQ(TestUnion::Union2::U2F0S1, reader.getUnion2().which());
  EXPECT_TRUE(reader.getUnion2().getU2f0s1());

  ASSERT_EQ(TestUnion::Union3::U3F0S64, reader.getUnion3().which());
  EXPECT_EQ(1234567890123456789ll, reader.getUnion3().getU3f0s64());
321 322 323 324

  // Can't access union members by name from the root.
  EXPECT_ANY_THROW(root.get("u0f1s32"));
  EXPECT_ANY_THROW(root.set("u0f1s32", 1234567));
325 326
}

327 328 329 330 331
TEST(DynamicApi, UnnamedUnion) {
  MallocMessageBuilder builder;
  StructSchema schema = Schema::from<test::TestUnnamedUnion>();
  auto root = builder.initRoot<DynamicStruct>(schema);

332
  EXPECT_EQ(schema.getFieldByName("foo"), KJ_ASSERT_NONNULL(root.which()));
333 334

  root.set("bar", 321);
335
  EXPECT_EQ(schema.getFieldByName("bar"), KJ_ASSERT_NONNULL(root.which()));
336 337 338 339 340 341
  EXPECT_EQ(321u, root.get("bar").as<uint>());
  EXPECT_EQ(321u, root.asReader().get("bar").as<uint>());
  EXPECT_ANY_THROW(root.get("foo"));
  EXPECT_ANY_THROW(root.asReader().get("foo"));

  root.set("foo", 123);
342
  EXPECT_EQ(schema.getFieldByName("foo"), KJ_ASSERT_NONNULL(root.which()));
343 344 345 346 347
  EXPECT_EQ(123u, root.get("foo").as<uint>());
  EXPECT_EQ(123u, root.asReader().get("foo").as<uint>());
  EXPECT_ANY_THROW(root.get("bar"));
  EXPECT_ANY_THROW(root.asReader().get("bar"));

348 349
  root.set("bar", 321);
  EXPECT_EQ(schema.getFieldByName("bar"), KJ_ASSERT_NONNULL(root.which()));
350 351 352 353 354
  EXPECT_EQ(321u, root.get("bar").as<uint>());
  EXPECT_EQ(321u, root.asReader().get("bar").as<uint>());
  EXPECT_ANY_THROW(root.get("foo"));
  EXPECT_ANY_THROW(root.asReader().get("foo"));

355 356
  root.set("foo", 123);
  EXPECT_EQ(schema.getFieldByName("foo"), KJ_ASSERT_NONNULL(root.which()));
357 358 359 360 361
  EXPECT_EQ(123u, root.get("foo").as<uint>());
  EXPECT_EQ(123u, root.asReader().get("foo").as<uint>());
  EXPECT_ANY_THROW(root.get("bar"));
  EXPECT_ANY_THROW(root.asReader().get("bar"));
}
362

Kenton Varda's avatar
Kenton Varda committed
363 364 365 366 367
TEST(DynamicApi, ConversionFailures) {
  MallocMessageBuilder builder;
  auto root = builder.initRoot<DynamicStruct>(Schema::from<TestAllTypes>());

  root.set("int8Field", 123);
368
  EXPECT_NONFATAL_FAILURE(root.set("int8Field", 1234));
Kenton Varda's avatar
Kenton Varda committed
369 370

  root.set("uInt32Field", 1);
371
  EXPECT_NONFATAL_FAILURE(root.set("uInt32Field", -1));
Kenton Varda's avatar
Kenton Varda committed
372 373

  root.set("int16Field", 5);
374
  EXPECT_NONFATAL_FAILURE(root.set("int16Field", 0.5));
Kenton Varda's avatar
Kenton Varda committed
375 376

  root.set("boolField", true);
377
  EXPECT_NONFATAL_FAILURE(root.set("boolField", 1));
Kenton Varda's avatar
Kenton Varda committed
378 379
}

380 381 382 383
TEST(DynamicApi, LateUnion) {
  MallocMessageBuilder builder;
  auto root = builder.initRoot<DynamicStruct>(Schema::from<test::TestLateUnion>());

384
  root.get("theUnion").as<DynamicStruct>().set("qux", "hello");
385 386 387
  EXPECT_EQ("hello", root.as<test::TestLateUnion>().getTheUnion().getQux());
}

388 389
TEST(DynamicApi, Has) {
  MallocMessageBuilder builder;
390
  auto root = builder.initRoot<DynamicStruct>(Schema::from<TestDefaults>());
391

392 393
  // Primitive fields are always present even if set to default.
  EXPECT_TRUE(root.has("int32Field"));
394 395 396
  root.set("int32Field", 123);
  EXPECT_TRUE(root.has("int32Field"));
  root.set("int32Field", -12345678);
397
  EXPECT_TRUE(root.has("int32Field"));
398

399
  // Pointers are absent until initialized.
400 401 402 403 404
  EXPECT_FALSE(root.has("structField"));
  root.init("structField");
  EXPECT_TRUE(root.has("structField"));
}

405 406
TEST(DynamicApi, HasWhenEmpty) {
  AlignedData<1> nullRoot = {{0, 0, 0, 0, 0, 0, 0, 0}};
407 408
  kj::ArrayPtr<const word> segments[1] = {kj::arrayPtr(nullRoot.words, 1)};
  SegmentArrayMessageReader reader(kj::arrayPtr(segments, 1));
409 410
  auto root = reader.getRoot<DynamicStruct>(Schema::from<TestDefaults>());

411 412
  EXPECT_TRUE(root.has("voidField"));
  EXPECT_TRUE(root.has("int32Field"));
413 414 415 416 417 418 419 420 421 422 423 424 425 426
  EXPECT_FALSE(root.has("structField"));
  EXPECT_FALSE(root.has("int32List"));
}

TEST(DynamicApi, SetEnumFromNative) {
  MallocMessageBuilder builder;
  auto root = builder.initRoot<DynamicStruct>(Schema::from<TestAllTypes>());

  root.set("enumField", TestEnum::BAZ);
  root.set("enumList", {TestEnum::BAR, TestEnum::FOO});
  EXPECT_EQ(TestEnum::BAZ, root.get("enumField").as<TestEnum>());
  checkList<TestEnum>(root.get("enumList"), {TestEnum::BAR, TestEnum::FOO});
}

427 428 429 430 431 432 433 434
TEST(DynamicApi, SetDataFromText) {
  MallocMessageBuilder builder;
  auto root = builder.initRoot<DynamicStruct>(Schema::from<TestAllTypes>());

  root.set("dataField", "foo");
  EXPECT_EQ(data("foo"), root.get("dataField").as<Data>());
}

435 436 437 438 439
TEST(DynamicApi, BuilderAssign) {
  MallocMessageBuilder builder;
  auto root = builder.initRoot<DynamicStruct>(Schema::from<TestAllTypes>());

  // Declare upfront, assign later.
440
  // Note that the Python implementation requires defaulted constructors.  Do not delete them!
441
  DynamicValue::Builder value;
442 443
  DynamicStruct::Builder structValue;
  DynamicList::Builder listValue;
444 445 446 447 448 449 450 451 452 453

  value = root.get("structField");
  structValue = value.as<DynamicStruct>();
  structValue.set("int32Field", 123);

  value = root.init("int32List", 1);
  listValue = value.as<DynamicList>();
  listValue.set(0, 123);
}

454
}  // namespace
455
}  // namespace _ (private)
456
}  // namespace capnp